🎧 New: AI-Generated Podcasts Turn your study notes into engaging audio conversations. Learn more

CS3224_Lect_09_20241001 (2).pdf

Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Transcript

Process Termination Process executes last statement and then asks the operating system to delete it using the exit() system call. This causes: Returns status data from child to parent (via the parent calling wait()) Process’ resources are deallocated by operating system In L...

Process Termination Process executes last statement and then asks the operating system to delete it using the exit() system call. This causes: Returns status data from child to parent (via the parent calling wait()) Process’ resources are deallocated by operating system In Linux, exit usually takes one parameter indicating an error if non-zero. exit is called implicitly upon return from the main routine of a program. Parent may terminate the execution of children processes using the abort() system call (TerminateProcess() in windows). Some reasons for doing so: Child has exceeded allocated resources Task assigned to child is no longer required The parent is exiting and the operating systems does not allow a child to continue if its parent terminates Process Termination Some operating systems do not allow a child to exist if its parent has terminated. Hence, in such systems, if a process terminates, then the OS terminates all its children. cascading termination - All children, grandchildren, etc. are terminated. The termination is initiated by the operating system. (this is not the case in Linux) The parent process may wait for termination of a child process by using the wait()system call. The call returns status information and the pid of the terminated process int status; pid = wait(&status); When a process exits, its resources are deallocated except its entry in the process table (containing the exit status). Only after the parent invokes the wait() function which reads that status that its entry in the process table is released. Till then, the terminated child process is a zombie. If a parent terminated before the child (i.e. without invoking wait), the running child process is an orphan (if allowed by OS, e.g. Linux) and its new parent becomes the init process (whose PID is 1). The init process periodically invokes wait in order to release orphan zombie processes. Multiprocess Architecture – Chrome Browser Many web browsers ran as single process (some still do) If one web site causes trouble, entire browser can hang or crash Mozilla Firefox and Google Chrome Browsers are multi-process with 3 different types of (communicating) processes: A browser process manages user interface, disk and network I/O One or more renderer processes renders web pages, deals with HTML, Javascript, etc. A new renderer created for each tab/website opened Since each tab is a separate process, they don’t share memory. They also do not share file resources based on how their parent process (the browser) created them, thus minimizing effect of security exploits. If a renderer crashes, it doesn’t bring down the entire browser. One or more plug-in processes for each type of plug-in 3.4 Inter-process Communication (IPC) Processes within a system may be independent or cooperating Cooperating process can affect or be affected by other processes, including sharing data Reasons for cooperating processes: Information sharing (e.g. shared file such as a database) Computation speedup (if system has multiple CPU cores) Modularity (may divide a program into tasks, may feed or use services of other tasks) Convenience (e.g. a user may be editing while a spell check is running) Cooperating processes need interprocess communication (IPC) Two models of IPC Shared memory Message passing Communications Models (a) Message passing. (b) shared memory. Producer-Consumer Problem The producer-consumer problem is a common paradigm for cooperating processes. The producer process produces information that is consumed by a consumer process, e.g. Multiple subtasks forming wider function such as a compiler producing an object file and a linker task consuming object files to produce the executable code. A client producing window commands (e.g. draw a rectangle) and an X11 display server consuming window commands. An X11 display server producing mouse/keyboard data and a client process receiving mouse clicks or keyboard keys. These were general examples of processes producing and consuming information. X11 servers generally communicate using message passing (via Unix pipes or TCP/IP sockets). 3.4.1 Shared memory systems An area of memory shared among the processes that wish to communicate (the creation of this area is facilitated by the OS kernel since each process normally has a separate address space) After the shared memory has been created by the OS, the mechanism used for communication between the user processes is administered by them, not the operating system. A major issue is to provide a mechanism that allows the user processes to synchronize their actions when they access shared memory locations. The communicating processes may use synchronization functions provided by the OS kernel. This shall be discussed in great details in the next chapter. Producer-Consumer Problem The producer-consumer problem may be solved using shared memory. It may also be solved using message passing communication as we shall see later. Two types of buffers may be used unbounded-buffer places no practical limit on the size of the buffer bounded-buffer assumes that there is a fixed buffer size The producer-consumer problem with shared bounded buffer BUF_SZ -1 Producer task Shared consumer task Memory tail head 0 Bounded-Buffer – Shared-Memory Solution BUF_SZ -1 Shared data: #define BUF_SZ 10 typedef struct {... } item; item buffer[BUF_SZ]; int in = 0; // tail in int out = 0; // head out Buffer needs to be administered 0 and used as a FIFO or Queue Bounded-Buffer – Shared-Memory Solution Shared data: out 1 (head) #define BUF_SZ 10 typedef struct { 0 in... (tail) } item; n-1 item buffer[BUF_SZ]; int in = 0; // tail int out = 0; // head Buffer needs to be administered and used as a FIFO or Queue in out out in in out Initial state After a few After a few writes/reads - writes/reads - No wrapping OR Only the “in” Both ‘in” and “out” wrapped but not wrapped the “out” index Bounded-Buffer – This is Bounded Buffer – Producer pseudocode, NOT actual Consumer code item next_produced; item next_consumed; while (true) { while (true) { Busy-wait loop Busy-wait while (in == out); loop next_consumed = buffer[out]; out = (out + 1) % BUF_SZ; while (((in + 1) % BUF_SZ) == out); buffer[in] = next_produced; } in = (in + 1) % BUF_SZ; } Solution is correct, but can only use BUFFER_SIZE-1 elements (why?) In this solution, the producer and consumer do not access the same item simultaneously What happens if both need to access the same location concurrently (e.g. a shared variable or a shared counter? Synchronization will then be needed (next chapter) → can’t do that for now 3.5 Examples of IPC Systems – POSIX shared memory A process first creates shared memory segment using shm_open shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666); Unrelated processes (i.e. ones without a parent-child relationship) needing to communicate via shared memory must know the name of this memory-mapped object. The last parameter is the file permissions. The function returns a file descriptor. Same function is also used to open an existing memory segment to share it A process may then use ftruncate to set the size of the object (in bytes). mmap may then be used to map and obtain a pointer to the shared memory. void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); Now the process could write to the shared memory, e.g. sprintf(shared_mem_ptr, "Writing to shared memory");

Use Quizgecko on...
Browser
Browser