You are on page 1of 54

Silberschatz, Galvin and Gagne 2009

Operating System Concepts 8


th
Edition
Silberschatz, Galvin and Gagne 2009
Multithreaded Programming
Modified by M.Rebaudengo - 2013
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.2
Single Thread vs. Multithreads
In traditional operating systems, each process has an address space and a
single thread of control
There are frequently solutions in which it is desirable to have multiple
threads of control in the same address space running concurrently, as
though they are (almost) separate processes.
Process A
Thread 1
Process B
Thread1
Thread2
Thread3
Thread4
Monothreaded process Multithreaded process
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Processes and Threads
Process combines two concepts
Concurrency
Each process is a sequential execution stream of instructions
Protection
Each process defines an address space
Address space identifies all addresses that can be touched by the
program
Threads
Key idea: separate the concepts of concurrency from protection
A thread is a sequential execution stream of instructions
A process defines the address space that may be shared by multiple
threads
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.4
Why Threads?
Parallel execution: the same process is executed in parallel on a multicore
CPU
Shared resources faster communication without serialization
easier to create and destroy than processes (100x)
useful if some are I/O-bound overlap computation and I/O
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.5
Example of multithreads (I)
Consider how a Web server can improve performance and interactivity by
using threads.
When a Web server receives requests for images and pages from many
clients, it serves each request (from each client) with a different thread
The process that receives all the requests, creates a new separate
thread for each request received
This new thread sends the required information to the remote client.
While this thread is doing its task, the original thread is free to accept
more requests
Web servers are multiprocessor systems that allow for concurrent
completion of several requests, thus improving throughput and
response time.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.6
How Can it Help?
Create a number of threads, and for each thread do
get network message from client
get URL data from disk
send data over network
What did we gain?
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.7
Overlapping Requests (Concurrency)
get network message (URL) from client
get URL data from disk
send data over network
get network message (URL) from client
get URL data from disk
send data over network
Request 1
Thread 1
Request 2
Thread 2
Time
(disk access latency)
(disk access latency)
Total time is less than request 1 + request 2
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.8
Example of multithreads (II)
Consider a word processor composed of the following threads:
a thread interacts with the user
a thread handles reformatting the document in the background and
performing spell checking
a thread handles the disk backups without interfering with the others in
order to automatically save the entire file every few minutes to protect
the user against losing the work in the event of program crash.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Threads
A thread lives within a process
A process can have several threads
A thread possesses an independent flow of control, and can be scheduled to run
separately from other threads, because it maintains its own:
stack
registers (CPU state)
The other resources of the process are shared by all its threads:
code
memory
open files
and more...
Threads are lightweight
Creating a thread is more efficient than creating a process
Communication between threads is easier than between processes
Context switching between threads requires fewer CPU cycles and memory
references than switching processes
Threads only track a subset of process state (share list of open files, pid, ).
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Single and Multithreaded Processes
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.11
Performance Benefits
It takes far less time to create a new thread in an existing process than to
create a new process
It takes less time to terminate a thread than a process
It takes less time to switch between 2 threads within the same process than
to switch between processes
Threads between the same process share memory and files: they can
communicate with each other without invoking the kernel.
If there is an application (or function) that should be implemented as a set of
related units of execution, it is far more efficient to do so as a collection of
threads rather than a collection of separate processes.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.12
Thread Model
Items shared by all threads in a process Items private to each thread
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.13
Thread Control Block (TCB)
Each thread has:
an identifier,
a set of registers (including the program counter and stack pointer)
a set of attributes (including the state, the stack size, scheduling
parameters, etc).
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Threads vs. Processes
Threads
A thread has no data segment or
heap
A thread cannot live on its own, it
must live within a process
There can be more than one thread
in a process, the first thread calls
main and has the processs stack
If a thread dies, its stack is
reclaimed
Inter-thread communication via
memory
Each thread can run on a different
physical processor
Inexpensive creation and context
switch
Processes
A process has code/data/heap &
other segments
There must be at least one thread in
a process
Threads within a process share
code/data/heap, share I/O, but each
has its own stack and registers
If a process dies, its resources are
reclaimed and all threads die
Inter-process communication via OS
and data copying
Each process can run on a different
physical processor
Expensive creation and context
switch
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Implementing Threads
Processes define an address
space; threads share the address
space
Process Control Block (PCB)
contains process-specific
information
Owner, PID, heap pointer,
priority, active thread, and
pointers to thread information
Thread Control Block (TCB)
contains thread-specific information
Stack pointer, PC, thread state
(running, ), register values, a
pointer to PCB,
Code
Initialized data
Heap
DLLs
mapped segments
Processs
address space
Stack thread1
PC
SP
State
Registers

TCB for
Thread1
Stack thread2
PC
SP
State
Registers

TCB for
Thread2
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Threads Life Cycle
Threads (just like processes) go through a sequence of start, ready, running,
waiting, and done states
Running Ready
Waiting
Start
Done
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.17
Threads vs. Processes
Threads use and exist within the process resources
A thread maintains its own stack and registers, scheduling properties,
set of pending and blocked signals.
Secondary Threads vs. Initial Threads
An initial thread is created automatically when a process is created.
Secondary threads are peers.
Threads vs. Processes
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.18
Thread Libraries
Thread libraries provide programmer with APIs (Application Programming
Interface) for creating and managing threads
Two primary ways of implementing
User-Level Threads (ULT): library entirely in user space (invoking a
function in the library results in a local function call in user space and
not a system call)
Kernel-Level Threads (KLT): Kernel-level library supported by the OS
(system call).
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.19
User-Level Thread
All of the work of thread management is done by the application and the
kernel is not aware of the existence of threads
An application can be programmed to be multithreading by using a threads
library, which is a package of routines for thread management
Threads library contains code for:
creating and destroyng threads
passing data between threads
scheduling thread execution
saving and restoring thread context.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.20
User LeveL Threads
Implemented as a thread library, which contains the code for thread
creation, termination, scheduling and switching
Kernel sees one process and it is unaware of its thread activity
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.21
User-Level Thread
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.22
ULT: behavior (I)
By default, an application begins with a single thread and begins running the thread
This application and its thread are allocated to a single process managed by the
kernel
At any time that the application is running (i.e., the process is in the Running state),
the application may spawn a newthread to run within the same process. Spawning is
done by invoking the spawn utility in the threads library. Control is passed to that
utility by a procedure call
The threads library creates a data structure for the new thread and then passes
control to one of the threads, within this process, in the Ready state using some
schedulingalgorithm
When control is passed to the library, the context of the current thread is saved, and
when the control is passed fromthe library to a thread the context of that thread is
restored. The context consists of the contents of user registers, the programcounter
and the stack pointers.
All the previous activities takes place in the user space and within a single process.
The kernel is anaware of this activity.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.23
ULT: behavior (II)
The kernel continues to schedule the process as a unit and assigns a single
execution state (Running, Blocked, Ready, etc.) to that process
When a thread does something that may cause it to become blocked locally
(e.g., waiting for another thread in its process to complete some work), it
calls a procedure in the threads library
This procedure checks if the thread must be put into blocked state. If so, it
saves its context, calls the thread scheduler to pick another thread to run
The thread scheduler looks in the thread table for a ready thread to run and
restores its context
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.24
User-level Threads Scheduling
B1, B2, B3,
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.25
User-level threads: comments
+ Fast to create and switch
procedures that saves the thread's state and the scheduler are user
procedures
no system call is needed
no context switch is needed
- When a ULT executes a system call, all the threads within the process are
blocked
E.g., read from file can block all threads
- User-level scheduler can fight with kernel-level scheduler
- A multithread application cannot take advantage of multiprocessing. A
kernel assigns one process to only one processor at a time. There are
applications that would benefit the ability to execute portions of code
simultaneously.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.26
Kernel-Level Threads
The kernel knows the threads and manges them
There is no thread table in each process. Instead, the kernel has a thread
table that keeps track of all the threads in the system
When a process wants to create a new thread or destroy an existing thread,
it makes a kernel call, which then does the creation or destruction by
updating the kernel thread table
The thread table containing TCBs holds the same information as with the
ULT, but now kept in the kernel instead of in user space.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.27
Kernel-Level Threads
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.28
Kernel Level Threads
Thread management done by the kernel
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.29
Kernel-level Threads Scheduling
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Kernel-level threads
+ Kernel-level threads do not block process for a system call
if one thread in a process is blocked by a system call (e.g., for a
page fault), the kernel can easily check if the process has one
thread ready to run
+ Only one scheduler (and kernel has global view)
- Can be difficult to make efficient (create & switch)
Kernel-level threads: comments
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.31
Pthreads
May be provided either as user-level or kernel-level
A POSIX standard (IEEE 1003.1c) API to:
create and destroy threads
synchronize threads and lock program resources
manage thread scheduling
API specifies behavior of the thread library, implementation is up to the
development of the library
Common in UNIX operating systems (Solaris, Linux, Mac OS X).
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.32
pthread_create()
Synthax:
pt hr ead_cr eat e( t hr ead, at t r , st ar t _r out i ne, ar g)
Arguments:
t hr ead: a unique identifier for the new thread returned by the
subroutine.
at t r : it specifies a thread attributes object, or NULL for the default
values.
st ar t _r out i ne: the C routine that the thread will execute once it is
created.
ar g: A single argument that may be passed to start_routine. It must be
passed by reference as a pointer cast of type void. NULL may be used if
no argument is to be passed.
Return value:
If successfull, it returns 0. Otherwise, it returns a nonzero error code.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.33
#i ncl ude <st di o. h>
#i ncl ude <pt hr ead. h>
mai n( ) {
pt hr ead_t f 2_t hr ead, f 1_t hr ead, f 3_t hr ead; i nt i 1=1, i 2=2;
voi d *f 2( ) , *f 1( ) , *f 3( ) ;
pt hr ead_cr eat e( &f 1_t hr ead, NULL, f 1, &i 1) ;
pt hr ead_cr eat e( &f 2_t hr ead, NULL, f 2, &i 2) ;
pt hr ead_cr eat e( &f 3_t hr ead, NULL, f 3, NULL) ;

}
voi d *f 1( i nt *i ) {

}
voi d *f 2( i nt *i ) {

}
voi d *f 3( ) {
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.34
pthread_exit()
When a thread has finished its work, it can exit by calling the
pt hr ead_exi t ( ) library procedure
The thread then vanishes and is no longer schedulable and the stack is
released.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.35
Example
#i ncl ude <st di o. h>
#i ncl ude <st dl i b. h>
#i ncl ude <si gnal . h>
#i ncl ude <sys/ t ypes. h>
#i ncl ude <uni st d. h>
#i ncl ude <pt hr ead. h> / * POSI X t hr eads */
voi d *myt hr ead( voi d *) ;
int sharedVar ; /* global variable */
i nt mai n( ) {
pt hr ead_t t i d;
shar edVar = 1234;
pr i nt f ( " Mai n: shar edVar = %d\ n" , shar edVar ) ;
pt hr ead_cr eat e( &t i d, NULL, myt hr ead, NULL) ;
sl eep( 1) ; / * yi el d t o anot her t hr ead */
pr i nt f ( " Mai n: shar edVar = %d\ n" , shar edVar ) ;
shar edVar = 999;
pr i nt f ( " Mai n: shar edVar = %d\ n" , shar edVar ) ;
sl eep( 1) ; / * yi el d t o anot her t hr ead */
pr i nt f ( " Mai n: shar edVar = %d\ n" , shar edVar ) ;
pr i nt f ( " DONE\ n" ) ;
exi t ( 0) ;
}
voi d *myt hr ead ( voi d *ar g)
{
/ * di spl ay t he val ue of t he gl obal var i abl e */
pr i nt f ( "t hr ead %l u: shar edVar i s %d \ n" , pt hr ead_sel f ( ) , shar edVar ) ;
shar edVar = 111;
pr i nt f ( "t hr ead %l u: shar edVar i s %d \ n" , pt hr ead_sel f ( ) , shar edVar ) ;
sl eep( 1) ; / * yi el d t o anot her t hr ead or mai n */
pr i nt f ( "t hr ead %l u: shar edVar i s %d \ n" , pt hr ead_sel f ( ) , shar edVar ) ;
shar edVar = 222;
pr i nt f ( "t hr ead %l u: shar edVar i s %d. \ n" , pt hr ead_sel f ( ) , shar edVar ) ;
sl eep( 1) ; / * yi el d t o anot her t hr ead or mai n */
/ * t hr ead exi t wi t h an i nt eger */
pt hr ead_exi t ( NULL) ;
}
OUTPUT
Main: sharedVar= 1234
thread 792: sharedVar is 1234
thread 792: sharedVar is 111
Main: sharedVar= 111
Main: sharedVar= 999
thread 792: sharedVar is 999
thread 792: sharedVar is 222
Main: sharedVar= 222
DONE
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.36
Example
#i ncl ude <st di o. h>
#i ncl ude <st dl i b. h>
#i ncl ude <pt hr ead. h>
#def i ne NUM_THREADS 5
voi d *Pr i nt Hel l o ( voi d *t hr eadi d)
{
l ong * t i d;
t i d = ( l ong *) t hr eadi d;
pr i nt f ( " Hel l o Wor l d! I t ' s me, t hr ead #%l d! \ n" , * t i d) ;
pt hr ead_exi t ( NULL) ;
}
i nt mai n( i nt ar gc, char *ar gv[ ] )
{
pt hr ead_t t hr eads[ NUM_THREADS] ;
i nt r c;
l ong t ;
f or ( t =0; t <NUM_THREADS; t ++) {
pr i nt f ( " I n mai n: cr eat i ng t hr ead %l d\ n" , t ) ;
r c = pt hr ead_cr eat e( &t hr eads[ t ] , NULL, Pr i nt Hel l o, ( voi d *) &t ) ;
i f ( r c) {
pr i nt f ( " ERROR; r et ur n code f r ompt hr ead_cr eat e( ) i s %d\ n" , r c) ;
exi t ( - 1) ;
}
}
pt hr ead_exi t ( NULL) ;
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.37
Example
#i ncl ude <st di o. h>
#i ncl ude <st dl i b. h>
#i ncl ude <pt hr ead. h>
#def i ne NUM_THREADS 5
voi d *Pr i nt Hel l o ( voi d *t hr eadi d)
{
l ong * t i d;
t i d = ( l ong *) t hr eadi d;
pr i nt f ( " Hel l o Wor l d! I t ' s me, t hr ead #%l d! \ n" , * t i d) ;
pt hr ead_exi t ( NULL) ;
}
i nt mai n( i nt ar gc, char *ar gv[ ] )
{
pt hr ead_t t hr eads[ NUM_THREADS] ;
i nt r c;
l ong t ;
f or ( t =0; t <NUM_THREADS; t ++) {
pr i nt f ( " I n mai n: cr eat i ng t hr ead %l d\ n" , t ) ;
r c = pt hr ead_cr eat e( &t hr eads[ t ] , NULL, Pr i nt Hel l o, ( voi d *) &t ) ;
i f ( r c) {
pr i nt f ( " ERROR; r et ur n code f r ompt hr ead_cr eat e( ) i s %d\ n" , r c) ;
exi t ( - 1) ;
}
}
pt hr ead_exi t ( NULL) ;
}
In main: creating thread 0
In main: creating thread 1
Hello World! It's me, thread #0!
In main: creating thread 2
Hello World! It's me, thread #1!
Hello World! It's me, thread #2!
In main: creating thread 3
In main: creating thread 4
Hello World! It's me, thread #3!
Hello World! It's me, thread #4!
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.38
Multiple arguments via a structure: example
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
char *messages[NUM_THREADS];
struct thread_data
{
int thread_id;
int sum;
char *message;
};
struct thread_data thread_data_array[NUM_THREADS];
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.39
void *PrintHello(void *threadarg)
{
int taskid, sum;
char *hello_msg;
struct thread_data *my_data;
sleep(1);
my_data = (struct thread_data *) threadarg;
taskid = my_data->thread_id;
sum = my_data->sum;
hello_msg = my_data->message;
printf("Thread %d: %s Sum=%d\n", taskid, hello_msg, sum);
pthread_exit(NULL);
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.40
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int *taskids[NUM_THREADS];
int rc, t, sum =0;
messages[0] ="English: Hello World!";
messages[1] ="French: Bonjour, le monde!";
messages[2] ="Spanish: Hola al mundo";
messages[3] ="German: Guten Tag, Welt!";
messages[4] ="Russian: Zdravstvytye, mir!";
for(t=0;t<NUM_THREADS;t++) {
sum =sum +t;
thread_data_array[t].thread_id =t;
thread_data_array[t].sum =sum;
thread_data_array[t].message =messages[t];
printf("Creating thread %d\n", t);
rc =pthread_create(&threads[t], NULL, PrintHello, (void *) &thread_data_array[t]);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.41
pthread_join()
In some thread systems, one thread can wait for a (specific) thread to exit
by calling the pt hr ead_j oi n( ) procedure
This procedure blocks the calling thread until (a specific) thread has exited
The thread identifier of the thread to wait for is given as a parameter.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.42
Example
void *howdy(void *vargp);
int main() {
pthread_t tid;
pthread_create(&tid, NULL, howdy, NULL);
pthread_join(tid, NULL);
exit(0);
}
/* thread routine */
void *howdy(void *vargp) {
printf("Hello, world!\n");
pthread_exit(NULL);
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.43
Execution
main thread
peer thread
pthread_exit()
main thread waits for
peer thread to terminate
exit()
terminates
main thread and
any peer threads
call Pthread_create()
call Pthread_join()
Pthread_join() returns
printf()
(peer thread
terminates)
Pthread_create() returns
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.44
Example
#i ncl ude <st di o. h>
#i ncl ude <st dl i b. h>
#i ncl ude <pt hr ead. h>
#def i ne NTHREADS 5
voi d *myFun ( voi d *x)
{
i nt t i d;
t i d = *( ( i nt *) x) ;
pr i nt f ( " Hi f r omt hr ead %d! \ n" , t i d) ;
pt hr ead_exi t ( NULL) ;
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.45
i nt mai n( i nt ar gc, char *ar gv[ ] )
{
pt hr ead_t t hr eads[ NTHREADS] ;
i nt t hr ead_ar gs[ NTHREADS] ;
i nt r c, i ;
/ * spawn t he t hr eads */
f or ( i =0; i <NTHREADS; ++i )
{
t hr ead_ar gs[ i ] = i ;
pr i nt f ( " spawni ng t hr ead %d\ n" , i ) ;
r c = pt hr ead_cr eat e( &t hr eads[ i ] , NULL, myFun, ( voi d *) &t hr ead_ar gs[ i ] ) ;
}
/ * wai t f or t hr eads t o f i ni sh */
f or ( i =0; i <NTHREADS; ++i ) {
r c = pt hr ead_j oi n( t hr eads[ i ] , NULL) ;
}
r et ur n 1;
}
Output:
spawning thread 0
spawning thread 1
Hi from thread 0!
spawning thread 2
Hi from thread 1!
spawning thread 3
Hi from thread 2!
spawning thread 4
Hi from thread 3!
Hi from thread 4!
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.46
Example
A program implementing the summation function where the summation
operation is run as a separate thread.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.47
Solution
#include <pthread.h>
#include <stdio.h>
int sum; /* this data is shared by the thread(s) */
void *runner(void *param); /* the thread */
int main(int argc, char *argv[])
{
pthread_t tid; /* the thread identifier */
if (argc !=2) {fprintf(stderr,"usage: a.out <integer value>\n");
return -1; }
if (atoi(argv[1]) <0) {
fprintf(stderr,"Argument %d must be non-negative\n",atoi(argv[1]));
return -1;
}
/* create the thread */
pthread_create(&tid,NULL,runner,argv[1]);
/* now wait for the thread to exit */
pthread_join(tid,NULL);
printf("sum =%d\n",sum);
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.48
/**
* The thread will begin control in this function
*/
void *runner(void *param)
{
int i, upper =atoi(param);
sum =0;
if (upper >0) {
for (i =1; i <=upper; i++)
sum +=i;
}
pthread_exit(0);
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.49
Exercise
Write a counting program, which should have 2 threads
While the peer thread loops, incrementing a counter, the main thread peeks
at the counter every second and prints its value
After 10 iterations, the main thread kills the peer one and computes the
average number of counts.
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.50
#i ncl ude <st di o. h>
#i ncl ude <st dl i b. h>
#i ncl ude <pt hr ead. h>
#i ncl ude <uni st d. h>
#i ncl ude <er r no. h>
char r unni ng = 1;
l ong l ong count er = 0;
voi d * pr ocess( )
{
whi l e ( r unni ng)
count er ++;
pr i nt f ( " Thr ead: exi t \ n" ) ;
pt hr ead_exi t ( NULL) ;
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.51
i nt mai n( )
{
i nt i ;
pt hr ead_t t hr ead_I d;
i f ( pt hr ead_cr eat e( &t hr ead_I d, NULL, pr ocess, NULL) )
{
pr i nt f ( "ERROR i n pt hr ead_cr eat e( ) \ n" ) ;
exi t ( - 1) ;
}
f or ( i =0 ; i < 10 ; i ++)
{
sl eep( 1) ;
pr i nt f ( "count er = %l l d\ n", count er ) ;
}
r unni ng = 0;
pt hr ead_j oi n( t hr ead_I d, NULL) ;
pr i nt f ( "Aver age I nst r uct i ons = %l l d \ n", count er / 10) ;
r et ur n 0;
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.52
Thread and Processes
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
int value =0; /* this data is shared by the thread(s) */
void *runner(void *param); /* the thread */
void *runner(void *param)
{
value =5;
pthread_exit(0);
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.53
int main(int argc, char *argv[])
{
pid_t pid;
pthread_t tid; /* the thread identifier */
pid =fork();
if (pid ==0) {/* child process */
pthread_create(&tid, NULL,runner,NULL);
/* now wait for the thread to exit */
pthread_join(tid,NULL);
printf(" CHILD: value = %d\n" ,value);
}
else if (pid >0) {/* parent process */
wait(NULL);
printf(" PARENT: value = %d\n" ,value);
}
}
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition 4.54
Semantics of fork() and exec()
Does fork() duplicate only the calling thread or all threads?
some UNIX systems have chosen to have two versions of fork():
one that duplicates all threads (forkall())
one that duplicates only the thread invoked by the fork() system call
(fork1())
If exec() is called immediately after forking, then duplicating all threads
is unnecessary. In this istance, duplicating only the calling thread is
appropriate.

You might also like