Process Concept

Memory Layout of a Process

Process in Memory
Layout of a process in memory

State of Process New: the process is being created.

Process State
Diagram of process state

Process Control Block

PCB
Process control block (PCB)

Summary

Process Scheduling

Scheduling Queue

ReadyQueueWaitQueue
The ready queue and wait queues
QueueingDiagram
Queueing-diagram representation of process scheduling

Context Switch

ContextSwitch
Diagram showing context switch from process to process

Operations on Processes

ProcessTree
A tree of processes on a typical Linux system
#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main()
{
    pid_t pid;
    // fork a child process
    pid = fork();
    if (pid < 0) { // error occurred
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0) { // child process
        execlp("/bin/ls", "ls", NULL);
    }
    else { // parent process
        wait(NULL);
        printf("Child Complete");
    }
    return 0;
}
CodeExample
Process creation using the fork() system call

Zombie and Orphan

Operations on Processes

#include <stdio.h>
#include <unistd.h>

int main()
{
    pid_t pid;
    pid = fork();
    printf("Hello, Process! %d\n", pid)

    return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int value = 5;

int main()
{
    pid_t pid;
    pid = fork();
    
    if (pid == 0) { // child process
        value += 15;
        return 0;
    }
    else if(pid > 0) { // parent process
        wait(NULL);
        printf("Parent: value = %d\n", value); // will be 5
    }

    return 0;
}
  1. fork()๋ฅผ ํ•˜๋ฉด parent์˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•˜์—ฌ child๋ฅผ ์ƒ์„ฑ
  2. parent๊ฐ€ wait์ด ๋˜๋ฉด, child๊ฐ€ ์ง„ํ–‰๋˜๋ฉด์„œ child ์˜์—ญ๋‚ด์˜ value๋ฅผ 5 ์ฆ๊ฐ€์‹œํ‚ค๊ณ  return
  3. ๊ทธ๋Ÿฌ๋‚˜, 2.์˜ ๊ฒฐ๊ณผ๋Š” parent ์˜์—ญ์˜ value์— ์˜ํ–ฅ์„ ๋ชป ์คŒ
  4. ๋”ฐ๋ผ์„œ, parent๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋˜๋ฉด์„œ print๋ฅผ ํ•  ๋•Œ, 5๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ
#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main() {
    /*
    * How many processes are created?
    * it will be 8
    * e.g. ์ฒซ๋ฒˆ์งธ fork()์ดํ›„ ์ƒ์„ฑ๋œ child process์™€ parent process ๋‘˜ ๋‹ค ๋‘ ๋ฒˆ์งธ fork()๋ฅผ ์‹คํ–‰ํ•จ
    */
    fork(); // fork a child process
    fork(); // fork another child process
    fork(); // and fork another

    /*
    * ์ด ๊ฒฝ์šฐ๋Š” 16๊ฐœ
    */
    int i;
    for(i = 0; i < 4; ++i)
        fork();
    
    return 0;
}
int main()
{
    pit_t pid;
    pid = fork();

    if (pid == 0) { // child process
        execlp("/bin/ls", "ls", NULL);
        printf("LINE J\n"); // ์‹คํ–‰๋˜์ง€ ๋ชปํ•จ
    }
    else if (pid > 0) { // parent process
        wait(NULL);
        printf("Child Complete\n");
    }

    return 0;
}
/*
* B = C
*/
int main()
{
    pid_t pid, pid1;
    pid = fork();
    if (pid == 0) { // child process
        pid1 = getpid();
        printf("child: pid = %d\n", pid); // A
        printf("child: pid1 = %d\n", pid1); // B
    }
    else if (pid > 0) { // parent process
        pid1 = getpid();
        printf("parent: pid = %d\n", pid); // C
        printf("parent: pid1 = %d\n", pid1); // D
        wait(NULL);
    }

    return 0;
}
#define SIZE 5
int nums[SIZE] = {0, 1, 2, 3, 4};

int main()
{
    pid_t pid;
    int i;
    pid = fork();

    if(pid == 0) { // child process
        for (i = 0; i < SIZE; ++i) {
            nums[i] *= i;
            printf("CHILD: %d \n", nums[i]); // 0, 1, 4, 9, 16
        }
    }
    else if (pid > 0) { // parent process
        wait(NULL);
        for (i = 0; i < SIZE; ++i) {
            printf("PARENT: %d \n", nums[i]); // 0, 1, 2, 3, 4
        }
    }

    return 0;
}

Interprocess Communication

IPC

IPCModel
Communication models: (a) Shared memory and (b) Message Passing

IPC in Shared-Memory Systems

/*
* define a shared buffer
*/
#define BUFFER_SIZE 10

typedef struct {
    ...
} item;

item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;

/*
* producer process using shared memory
*/
item next_produced;

while (true) {
    /* produce an item in next_produced */

    while (((in + 1) % BUFFER_SIZE) == out); // do nothing

    buffer[in] = next_produced;
    in = (in + 1) % BUFFER_SIZE;
}

/*
* consumer process using shared memory
*/
item next_consumed;

while (true) {
    while (in == out); // do nothing

    next_consumed = buffer[out];
    out = (out + 1) % BUFFER_SIZE;
}

IPC in Message-Passing Systems

/*
* producer process using message passing
*/
message next_produced;

while (true) {
    /* produce an item in next_produced */

    send(next_produced);
}

/*
* consumer process using message passing
*/
message next_consumed;

while (true) {
    receive(next_consumed);

    /* consume the item in next_consumed */
}

Examples of IPC Systems

POSIX Shared Memory

/*
* Producer process illustrating POSIX shared-memory API
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main()
{
    const int SIZE = 4096; // the size of shared memory
    const char *name = "OS"; // the name of shared memory
    const char *message_0 = "Hello, ";
    const char *message_1 = "Shared Memory!\n";

    int shm_fd; // the file descriptor of shared memory
    char *ptr; // pointer to shared memory

    /* create the shared memory object */
    shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);

    /* configure the size of the shared memory */
    ftruncate(shm_fd, SIZE);

    /* map the shared memory object */
    ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);

    /* write to the shared memory */
    sprintf(ptr, "%s", message_0);
    ptr += strlen(message_0);
    sprintf(ptr, "%s", message_1);
    ptr += strlen(message_1);

    return 0;
}
/*
* Consumer process illustrating POSIX shared-memory API
*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main()
{
    const int SIZE = 4096; // the size of shared memory
    const char *name = "OS"; // the name of shared memory

    int shm_fd; // the file descriptor of shared memory
    char *ptr; // pointer to shared memory

    /* create the shared memory object */
    shm_fd = shm_open(name, O_RDONLY, 0666);

    /* map the shared memory object */
    ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);

    /* read from the shared memory object */
    printf("%s", (char *)ptr);

    /* remove the shared memory */
    shm_unlink(name);

    return 0;
}

Pipes

Ordinary Pipes

OrdinaryPipe
File descriptors for an ordinary pipe
/*
* Ordinary pipe in UNIX
*/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1

int main()
{
    char write_msg[BUFFER_SIZE] = "Greetings;
    char read_msg[BUFFER_SIZE];
    int fd[2];
    pid_t pid;

    /* create the pipe */
    pipe(fd);

    pid = fork(); // fork a new process

    if (pid > 0) { // parent process
        close(fd[READ_END]);
        /* write to the pipe */
        write(fd[WRITE_END], write_msg, strlen(write_msg) + 1);
        close(fd[WRITE_END]);
    }
    else if (pid == 0) { // child process
        close(fd[WRITE_END]);
        /* read to the pipe */
        read(fd[READ_END], read_msg, BUFFER_SIZE);
        printf("read %s\n", read_msg);
        close(fd[READ_END]);
    }

    return 0;
}

Communication in Client-Server Systems

Socket

A socket is identified by an IP address concatenated with a port number.

Socket
Communication using sockets
/*
* Date server in Java
*/

import java.net.*;
import java.io.*;

public class DateServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(6013);

        /* Now listen for connections */
        while (true) {
        Socket client = server.accept();
        PrintWriter pout = new PrintWriter(client.getOutputStream(), true);

        /* write the Date to the socket */
        pout.println(new java.util.Date().toString());

        /* close the socket and resume listening for connections */
        client.close();
        }
    }
}
/*
* Date client in Java
*/

import java.net.*;
import java.io.*;

public class DateClient {
    public static void main(String[] args) throws Exception {
        /* make connection to server socket */
        Socket socket = new Socket("127.0.0.1", 6013);

        InputStream in = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(in));

        /* read date from the socket */
        String line = null;

        while ((line = br.readLine()) != null)
            System.out.println(line);

        /* close the socket connections */
        socket.close();
    }
}

RPC