lecture 5 process, thread and task september 22, 2015 kyu ho park

66
Lecture 5 Process, Thread and Task September 22, 2015 Kyu Ho Park

Upload: darren-baker

Post on 13-Dec-2015

218 views

Category:

Documents


0 download

TRANSCRIPT

Lecture 5Process, Thread and

TaskSeptember 22, 2015

Kyu Ho Park

Major Topics of Lect. 5 How to create a process. How to create a thread. What is the task?

2

creating a process

3

creating a process

4

5

Process Concept

An operating system executes a variety of programs: Batch system – jobs Time-shared systems – user programs or

tasks Process – a program in execution; process

execution must progress in sequential fashion A process includes:

program counter stack data section

6

Process in Memory

Stack

Heap

Data

Text

SP

PC

Memory Map of a process

Memory Map of a process4GB

3GBStack

text

data

heap

Virtualization

9

Processes are provided with 2 virtualizations:

• Virtualized Processor• Virtualized Memory

10

Process State

As a process executes, it changes state new: The process is being created running: Instructions are being executed waiting: The process is waiting for some

event to occur ready: The process is waiting to be

assigned to a process terminated: The process has finished

execution

11

Diagram of Process State

terminated

runningready

new admitted

waiting

interrupt

scheduler dispatch

I/O or event waitI/O or event completion

exit

12

Process Control Block (PCB)Information associated with each

process Process state Program counter CPU registers CPU scheduling information Memory-management information Accounting information I/O status information

13

Process management

RegistersProgram counterProgram status wordStack pointerProcess stateTime when process startedCPU time usedChildren’s CPU timeTime of next alarmMessage queue pointersPending signal bitsProcess idVarious flag bits

Memory management

Pointer to text segmentPointer to data segmentPointer to bss segmentExit statusSignal status Process idParent processProcess groupReal uidEffectiveReal gidEffective gidBit maps for signalsVarious flag bits

Files management

UMASK maskRoot directoryWorking directoryFile descriptorsEffective uidEffective gidSystem call parametersVarious flag bits

Some of the fields of the MINIX process table

Process Control Block(PCB)

14/39

Process Descriptor Overview of the Linux Process Descriptor ( struct

task_struct )

This seminar (chapter 3) focus on Process State

TASK_RUNNING TASK_INTERRUPTIBLE TASK_UNINTERRUPTIBLE TASK_STOPPED TASK_TRACED TASK_ZOMBIE EXIT_DEAD

Process parent/child Relationship

Process DescriptorProcess SwitchingCreating ProcessesDestroying Processes

Task List Representation of a process: A process

descriptor of the type struct task_struct //<linux/sched.h>1.7KBytes on a 32-bit machine

Task list: A circular doubly linked list of task_struct

15

16

CPU Switch From Process to ProcessP 0

Save state into PCB0

reload from PCB1

Save to PCB1

Reload from PCB0

OS P 1

idle

17

Operations on Processes: Process Creation Parent process create children processes,

which, in turn create other processes, forming a tree of processes

Possibilities of Resource sharing Parent and children share all resources Children share subset of parent’s

resources Parent and child share no resources

Possibilities of Execution Parent and children execute concurrently Parent waits until children terminate

18

Process Creation (Cont.) Possibilities of Address space

Child duplicate of parent Child has a program loaded into it

UNIX examples fork system call creates a new

process exec system call used after a fork

to replace the process’ memory space with a new program

fork()

19

Initial Process

fork()

Returns a new pid(child process)

Returns zero

Original ProcessContinues

New Process:Child

20

fork()

Stack

Heap

BSS

Data

Text . fork( ).

SP PC .

.

open files

.

.

Registers

Resources

pid=1000

ID

Stack

Heap

BSS

Data

Text . fork( ).

SP PC .

.

open files..

Registers

Resources

pid=1001

ID

Stack

Heap

BSS

Data

Text . fork( ).

SP PC .

.

open files

.

.

Registers

Resources

pid=1000

ID

ParentChild

PC

PCPC

fork()

21

forkOut

22

fork()

23

pid=999;

fork()

pid=1000;

parent child

pid=1234;

pid=1452;

pid=1345;

running

ready

fork()int main(){

int i;for(i=0; i<10; i++){

printf(“Process_id=%d, i=%d\n”, getpid(), i);

if(i==5){printf(“Process_id=%d: fork() to start\

n”,getpid());int forkValue=fork();printf(“forkValue=%d\n”, forkValue);

}}

}

24

fork( ) output

25

Creation of a process

26

•fork() system call : It creates a new process by duplicating an existing one. The process that calls fork() is the parent, and the new process is the child.•pid = fork();• in the parent process, pid is the child process ID and in the child process, pid=0;

•execve() system call : It creates a new address space and load a new program into it.

int execve(const char *filename, char *const argv[],

char *const envp[]);argv: command line argument;envp: path name, etc;

wait

exit()exec()

fork()

parentresumes

child

fork() - exec()-wait()

forkWait

fork()-wait() output

forkWaitExeclp

output

32

Process Termination Process executes last statement and asks the operating

system to delete it (exit) Output data from child to parent (via wait) Process’ resources are deallocated by operating

system Parent may terminate execution of children processes

(abort) Child has exceeded allocated resources Task assigned to child is no longer required If parent is exiting

Some operating system do not allow child to continue if its parent terminates

All children terminated - cascading termination

forkWait.c

33

Duplicating a process image#include <sys/types.h>#include <unistd.h>pid_t fork(void);

-return vaule of fork() : pid of the child if successful to the parent, 0 to the child.

If failed, -1 to the parent.-unistd.h : fork() prototype is defined.-types.h : pid_t is defined.

34

fork()1. #include <unistd.h>2. #include <sys/types.h>3. #include <stdio.h>4. #include <stdlib.h>5. main()6. { pid_t pid;7. printf("Start!\n");8. pid = fork();9. if( pid == 0) printf("I am the Child !\n");10. else if (pid > 0) printf("Parent pid=%d,

Child pid=%d\n", (int)getpid(),pid);11. else printf("fork() failed!\n");}

35

1. #include <unistd.h>2. #include <sys/types.h>3. #include <stdio.h>4. #include <stdlib.h>5. main()6. { pid_t pid;7. printf("Start!\n");8. pid = fork();9. if( pid == 0) printf("I am the Child !\n");10. else if (pid > 0) printf("Parent pid=%d,

Child pid=%d\n", (int)getpid(),pid);11. else printf("fork() failed!\n");}

1. #include <unistd.h>2. #include <sys/types.h>3. #include <stdio.h>4. #include <stdlib.h>5. main()6. { pid_t pid;7. printf("Start!\n");8. pid = fork();9. if( pid == 0) printf("I am the Child !\n");10. else if (pid > 0) printf("Parent pid=%d,

Child pid=%d\n", (int)getpid(),pid);11. else printf("fork() failed!\n");}

Original process

Parent process Child process

PC

PC+1 PC+1

pid ==0pid > 0

Replacing a process image#include <unistd.h>

char **environ;

int execl(const char *path, const char *arg0, …,(char *)0);int execlp(const char *file, const char *arg0,…,(char *)0);int execle(const char *path, const char *arg0,…,(char *)0,char *const envp[]);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execve(const char *path, char *const argv[],char *const envp[]);

36

Examples of exe*()#include <unistd.h>char *const ls_argv[]={“ls”,”-l”,0};

char *const ls_envp[]={“PATH=bin:/usr/bin”,”TERM=console”,0};

execl(“/bin/ls”,”ls”,”-l”,0);execlp(“ls”,”ls”,”-l”,0);execle(“/bin/ls”,”ls”,”-l”,0,ls_envp);execv(“/bin/ps”,ls_argv);execvp(“ls”,ls_argv);execve(“/bin/ls”, ls_argv, ls_envp);

37

Waiting for a process#include <sys/types.h>#include <sys/wait.h>

pid_t wait(int *status);

The parent process executing wait(), pauses until its child process stops. The call returns the pid of the child process

38

status status: it is the value transferred to

the parent by exit(int status).

39

Parent process: wait(&status)

Child process: exit(1);

0x00 0x00 0x64 0x00

0x00 0x00 0x00 0x64

exit(1)root@ubuntu:~/Test/FORK# ./forkwaitStart!Parent pid=25820, Child pid=25821I am the Child !status=256

If(pid !=0){int stat;pid_t pid_child;pid_child = wait(&status);printf(“Child has

finished,pid_child=%d\n”,pid_child);if(status !=0) printf(“Child finished normally\n”);else printf(“Child finished abnormally\n”);

}

40

41

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

main(){ pid_t pid; int status;

printf("Start!\n");

pid = fork();

if( pid == 0) { printf("I am the Child !\n"); exit(100); } else if (pid > 0){ printf("Parent pid=%d, Child pid=%d\n", (int)getpid(),pid); wait(&status); printf("status=%d\n", status); }

else printf("fork() failed!\n");}

root@ubuntu:~/Test/FORK# ./forkwaitStart!Parent pid=25789, Child pid=25790I am the Child !status=25600root@ubuntu:~/Test/FORK# vi forkwait.c

./forkwait

forkwait.c

exit()#include <stdlib.h>void exit(int status);

/*Terminating current process and transfer the status to the parent.The value of status ranges from 0 to 255 integer value. */

42

waitpid( )#include <sys/types.h>#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

pid : pid of the child,status : transferred from the child executing exit(status),options 0 : usual wait state, that is , the parent waits until the child process finishes, WNOHANG :the parent process does not stay at ‘wait’ state.

43

Zombie Processes

44

Terminated

runningready

new admitted

waiting

interrupt

scheduler dispatch

I/O or event waitI/O or event completion

exit

TTerminated

Exit_Zombie

Wait( )

forkZombie.c

45

forkZombie.c

46

47

Threads

47

•So far a process is a single thread of execution.

•The single thread of control allows the process to perform only one task . The user cannot simultaneously type in characters and run the spell checker with the same process.

•Therefore modern OSs have extended the process concept to allow a process to have multiple threads of execution.

48

Programcounter

Thread

Process

Computer

Computer

(a) (b)

(a)Three processes each with one thread. (b)One process with three threads.

Process and Threads

49

Thread Usage[Tanenbaum]

A word processor with three threads

Linux Implementation of Threads

In the Linux, each thread has a unique task_struct . Linux implements all threads as standard processes.

A thread in Linux is just a process that shares certain resources( such as an address space).

50

51

A Thread

Stack

Heap

BSS

Data

Text

SP PC .

.

open files

.

.

Registers

Resources

52

Sharing of threads

open files

.

.

SP PC .

.

Registers

Resources

Stack1

Heap

BSS

Data

Stack2

Text

SP PC .

.

Registers

Thread1

Thread2

Creating Threads: clone( )#include <sched.h>

int clone( int (*func)(void *), void *child_stack, int flags, void *func_arg,…);

/*The caller must allocate a suitably sized block in the argument child_stack. The stack grows downward, so the child_stack argument should point to the high end of the allocated block.*/

int main(){ int child_stack[4096]; …. clone(thread_func, (void *)(child_stack+4095), CLONE_THREAD, NULL); …..

}int thread_func(void *arg){ ….}

53

If the flag is set to CLONE_CHILD_CLEARID|CLONE_CHILD_SETTID,the creates one is a process.

clone() example#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <linux/unistd.h>#include <sched.h>

int thread_func(void *arg){ printf("Child :TGID(%d), PID(%d)\n",(int) getpid(),(int) syscall(__NR_gettid)); sleep(1); return 0;}

int main(void){ int pid; int child_stack[4096];

printf("Start!\n"); printf("Parent:TGID(%d), PID(%d)\n",(int)getpid(),(int) syscall(__NR_gettid));

clone (thread_func, (void *)(child_stack+4095), CLONE_VM | CLONE_THREAD | CLONE_SIGHAND, NULL);

sleep(1);

printf("End!\n"); return 0;}

54

pthread example#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <linux/unistd.h>#include <pthread.h>

void *pthread_func(void *data){ int id; int i=0; pthread_t t_id; id = *((int *)data); printf(“I am the created pthread.\n”); sleep(2);}

int main(void){ int pid, status; int a = 1; int b = 2; pthread_t p_thread[2];

printf("Start!\n");

55

if((pid = pthread_create(&p_thread[0], NULL, pthread_func, (void*)&a)) < 0){ perror("Creation0 failed! "); exit(1); } if((pid = pthread_create(&p_thread[1], NULL, pthread_func, (void*)&b)) < 0){ perror("Creation1 failed"); exit(2); }

pthread_join(p_thread[0], (void **)&status); printf("pthread_join0\n");

pthread_join(p_thread[1], (void **)&status); printf("pthread_join1\n");

printf(“The Parent.\n”);

printf("End!\n"); return 0;}

POSIX Threads(pthread)

2015. 9.1 Kyu Ho Park

CORE Lab.

Embedded Software

Pthread and LinuxThread Thread got attention with the advent

of the POSIX 1003.c specification. But not so popular.

LinuxThreads which was very close to the POSIX standard: 1996 .

POSIX Thread: NPTL(Native POSIX Thread Library) NGPT(New Generation POSIX Threads)

57

NPTL

POSIX(Portable OS Interface)

UNIX

Drawbacks of thread program

Difficult to write multi-threaded programs.

Difficult to debug multi-threaded programs.

58

pthread functions#include <pthread.h>int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);void pthread_exit(void *retval);

Int pthread_join(pthread_t th, void **thread_return);//equivalent to wait( ).

59

pthread_create, exit, and join

60

pthread_create()

pthread_exit()

pthread_join()Master_thread

created_

threads

pthread

61

pthread_create

62

Task ?In Linux,

Processes and threads are all represented bytask_struct.

Every task has its own unique id and it is represented at pid field of <task_struct>.

But, according to the POSIX standard, all threads of a process shoud have the same pid.Linux adopts tgid(thread group id) to satisfy the POSIX standard.Therefore,a task if it is a process : pid == tgid,

if it is a thread : pid != tgid and the child’s tgid has the same tgid of the parent.

63

Simultaneous execution of threads

1. #include <stdio.h>2. #include <unistd.h>3. #include <stdlib.h>4. #include <pthread.h>

5. void *thread_function(void *arg);6. int run_now = 1;7. char message[] = "Hello World";

8. int main() {9. int res;10. pthread_t a_thread;11. void *thread_result;12. int print_count1 = 0;

13. res = pthread_create(&a_thread, NULL, thread_function, (void *)message);

14. if (res != 0) {15. perror("Thread creation failed");16. exit(EXIT_FAILURE);17. }

18. while(print_count1++ < 20) {19. if (run_now == 1) {20. printf("1");21. run_now = 2;22. }23. else {24. sleep(1);25. }26. }

64

1. printf("\nWaiting for thread to finish...\n");2. res = pthread_join(a_thread, &thread_result);3. if (res != 0) {4. perror("Thread join failed");5. exit(EXIT_FAILURE);6. }7. printf("Thread joined\n");8. exit(EXIT_SUCCESS);9. }

10. void *thread_function(void *arg) {11. int print_count2 = 0;

12. while(print_count2++ < 20) {13. if (run_now == 2) {14. printf("2");15. run_now = 1;16. }17. else {18. sleep(1);19. }20. }

21. sleep(3);22. }

semaphore#include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned int value);- sem: points to a semaphore object, pshared: if 0, the semaphore is local to the current process, else the semaphore may be shared between processes(Linux does not support it). value: initial value of the semaphore.

int sem_wait(sem_t *sem);-This function waits until the semaphore is nonzero, and decreases the value of semaphore by 1.

int sem_post(sem_t *sem);-This function increases the value of the semaphore by 1.

int sem_destroy(sem_t *sem);

65

Synchronization with semaphore

#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <semaphore.h>

void *thread_function(void *arg);sem_t bin_sem;

#define WORK_SIZE 1024char work_area[WORK_SIZE];

int main() { int res; pthread_t a_thread; void *thread_result;

res = sem_init(&bin_sem, 0, 0); if (res != 0) { perror("Semaphore initialization failed"); exit(EXIT_FAILURE); } res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); }

66

printf("Input some text. Enter 'end' to finish\n"); while(strncmp("end", work_area, 3) != 0) { fgets(work_area, WORK_SIZE, stdin); sem_post(&bin_sem); } printf("\nWaiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf("Thread joined\n"); sem_destroy(&bin_sem); exit(EXIT_SUCCESS);}

void *thread_function(void *arg) { sem_wait(&bin_sem); while(strncmp("end", work_area, 3) != 0) { printf("You input %d characters\n", strlen(work_area) -1); sem_wait(&bin_sem); } pthread_exit(NULL);}