Todo

  • Add page for file descriptors
  • More info on message passing

Overview

A process is a program in execution, it is an entity maintained by the operating system.

A process consists of the following memory regions:

Pasted image 20241005173233.png

Info

It is the job of the OS to give the process memory space. How the process allocates and deallocates space in memory is decided by the program itself.

Note

Local variables assigned to the stack are removed when a function returns.

A process can have the following states (in a time-sharing OS):

process state diagram

Scheduling

This involves the OS selecting what processes to run on the CPU. The goal is to maximize CPU utilization in a multiprogramming OS.

The following structures are used to manage processes in the OS.

Long Term Scheduler

Short Term Scheduler

Creation

Processes can create other processes. There is a singular root process for any OS called the primordial process. A process that creates another one is called the parent process. The created process is called the child process.

Processes can choose to share regions of memory, Unix-like systems do not do this and each parent-child process has its own context.

Parent-child processes also execute concurrently. In Unix-like systems the wait() syscall can be used in the parent to wait for the child to complete.

Warning

Parent-child processes are not guaranteed to finish execution in any specific order. In order to ensure the synchronization of parent and child processes IPC mechanisms such as #Pipes or the wait() syscall can be used.

In Unix-like systems, creating a child process copies the entire context of the parent process and continues execution from the creation of the child process in the child process.

Inter-Process Communications

There are two main ways processes can communicate:

Shared Memory

Shared memory involves sharing some region of memory between processes. Each process can read and write to the memory region. This is typically a faster method of sharing data.

Warning

You can overwrite the data in shared memory from a process if not careful.

The following can be implemented for shared memory

Note

Most thread level communication is done via shared memory.


The following syscalls are used on Unix:

Message Passing

Message passing involves sending and receiving messages. Messages are typically not overwritten and is used when sending smaller amounts of data. It is also slower than sharing memory, although it is easier to sync processes.

Message passing provides two basic operations

Pipes

Also called anonymous pipes, they are the most basic form of IPC on all Unix systems. Pipes are unidirectional meaning they can only be used to communicate one way between processes. They can only be created between parent and child processes or sibling processes. Data is collected in FIFO order.

Warning

Pipes only exist as long as the processes that use them are alive. Any pre-mature exit will loose all data in a pipe.

Abstract

This works because using the pipe() syscall creates two new File Descriptors for messages to be passed through, one for reading and one for writing. Since File Descriptors are copied between parent and children processes they are allowed to pass messages through the pipes without any issues.


Pipes use the following syscall(s) in Unix:

Example:

/* Program used for syncing processes */

main()              
{               
  char *s, buf[1024];         
  int fds[2];                   
  s = "EECS 678. Pipe program 3\n";
                          
  /* create a pipe */    
  pipe(fds);          
                    
  if (fork() == 0) { 
    /* child process. */    
    printf("Child line 1\n"); 
    read(fds[0], s, strlen(s));
    printf("Child line 2\n"); 
  } else {  
    /* parent process */
    printf("Parent line 1\n"); 
    write(fds[1], buf, strlen(s));
    printf("Parent line 2\n"); 
  }                                
} 

FIFO

Also called named pipes, these are much more powerful than anonymyous pipes. These can be used by any number of processes and do not require the parent-child or sibling relationship between processes.

These appear as a special type of file in the file system. They only allow half-duplex communication between processes. This means that each process can choose to read OR write not both.

Note

There must be at least one writer and one reader open for the FIFO to operate. If there is not, the process will be blocked and in a waiting state.

If there are multiple readers of the FIFO the output of the writer can be distributed among the reading processes. It depends on the implementation in the OS however.

Message Queues

Message queues uses indirect communication or mailboxes. They are similar to #FIFO in the sense that queues can be used by multiple processes. Processes can also use any number of queues to communicate and both send and receive from a queue.

Note

#Synchronization may be required for queues, and the capacity of the queue is defined by the OS. This capacity can be changed by the user however.

When sending messages in a queue, you can specify the message type help receivers identify which type of message to receive from the queue.

Unix Domain Sockets

This is a two-way communication channel. Sockets are a special type of file in Unix-like systems and is mostly used for the server, client model where the server waits for user requests for data or processing. Usually, this utilizes UDP or TCP. Sockets are bi-directional.


The following system calls are used for Unix sockets:

Signals

Todo

Add section

Programming

Creating Processes

The fork() syscall can be used to create a child process.

int main()
{
     pid_t  ret;
	/* fork another process */
	ret = fork();
	if (ret < 0) { /* error occurred */
	  fprintf(stderr, "Fork Failed");
      exit(-1);
	}
	else if (ret == 0) { /* child process */
	  execlp("/bin/ls", "ls", NULL);
	}
	else { /* parent process */
	  /* parent will wait for the child to complete */
	  wait(NULL);
	  printf("Child Complete");
	  exit(0);
	}
}

Note

If the return value of fork() is < 0 the child process was not created. If the return value is == 0 we are "in" the child process.

Definitions

Process Control Block

The process control block or PCB contains metadata about a process. It is used for scheduling and context switching.

It holds the following information:


Context Switching

The process of storing and restoring state of a process on an operating system.

Note

The switch from kernel to user mode is a mode switch

Warning

Context switching is pure overhead and the OS does nothing useful when switching context.


Child Process

A child process is a process which was created by another process. In POSIX systems this can be done with the fork syscall.


Parent Process

A parent process is a process which has spawned another process (child process).

Note

There is a special parent process called the primordial process which is what spawns all user processes in an OS.


Zombie Process

A zombie process is a child process which has finished execution and is waiting for the parent to collect it's exit status.


Orphan Process

An orphan process is a child process which is still executing even though its parent has finished executing.

Note

If a process is orphaned it will be adopted by some other process which will become its new parent. There will always be a parent process to adopt an orphaned process as all processes in an OS are children of the primordial process.

Reference

  1. Kulkarni, Prasad Various Lectures The University of Kansas 2024

Related