Академический Документы
Профессиональный Документы
Культура Документы
}
void *runner(void *param)
{
value = 5;
pthread_exit(0);
}
4.40
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Exercise (cont.)
int main(int argc, char *argv[])
{
pid_t pid;
pthread_t tid; /* the thread identier */
pthread_attr_t attr; /* set of attributes for the thread */
pid = fork()
if (pid == 0) { /* child process */
pthread_attr_init(&attr);
pthread_create(&tid,&attr,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);
}
4.41
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Thread Libraries
! Thread libraries provide programmer with APIs 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).
4.42
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
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.
4.43
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
User-Level Thread
4.44
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
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 new thread 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
scheduling algorithm
! When control is passed to the library, the context of the current thread is saved, and
when the control is passed from the library to a thread the context of that thread is
restored. The context consists of the contents of user registers, the program counter
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.
4.45
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
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
4.46
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
User-level Threads Scheduling
4.47
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
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
" the memory cache does need to be ushed
! - When a ULT executes a system call, all the threads within the process are
blocked
" E.g., read from le can block all threads
! - User-level scheduler can ght 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
applcations that would benet the ability to execute portions of code
simultaneously.
4.48
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Exercise
When a user level thread does I/O it blocks the entire process.
1. True
2. False
4.49
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
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.
4.50
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Kernel-Level Threads
4.51
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Kernel-level Threads Scheduling
4.52
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
! Kernel-level threads
" + Kernel-level threads do not block process for 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 difcult to make efcient (create & switch)
Kernel-level threads: comments
4.53
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Multithreading Models
! Many-to-One#
! One-to-One#
! Many-to-Many
4.54
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Many-to-One (ULT)
! Many user-level threads mapped to single kernel thread
" the kernel has no knowledge of the application threads
! Examples:
" Solaris Green Threads
" GNU Portable Threads
4.55
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Many-to-One Model
4.56
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
One-to-One (KLT)
! Each user-level thread maps to kernel thread
! Examples
" Windows NT/XP/2000
" Linux
" Solaris 9 and later
4.57
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
One-to-one Model
4.58
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Many-to-Many Model
! Allows many user level threads to be mapped to many kernel
threads
! Allows the operating system to create a sufcient number of
kernel threads
! The threads library is responsible for scheduling user threads
on the available schedulable entities
! When a thread performs a blocking system call, the kernel can
schedule another thread for execution
! Examples:
" Solaris prior to version 9
" Windows NT/2000 with the ThreadFiber package
4.59
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Many-to-Many Model
4.60
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Two-level Model
! Similar to M:M, except that it allows a user thread to be
bound to kernel thread
! Examples
" IRIX
" HP-UX
" Tru64 UNIX
" Solaris 8 and earlier
4.61
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Two-level Model
4.62
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Windows XP Threads
! Implements the one-to-one mapping
! Each thread contains
" A thread id
" Register set
" Separate user and kernel stacks
" Private data storage area
! The register set, stacks, and private storage area are known
as the context of the threads
! The primary data structures of a thread include:
" ETHREAD (executive thread block)
" KTHREAD (kernel thread block)
" TEB (thread environment block)
4.63
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Linux Threads
! Linux refers to them as tasks rather than threads
! Thread creation is done through clone() system call
! clone() allows a child task to share the address space
of the parent task (process)
4.64
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Java Threads
! Java threads are managed by the JVM
4.65
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
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 resourses
" manage thread scheduling
! API species behavior of the thread library, implementation is up to
development of the library
! Common in UNIX operating systems (Solaris, Linux, Mac OS X).
4.66
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
pthread_create()
! Synthax:
" pthread_create(thread,attr,start_routine,arg)
! Arguments:
" thread: A unique identier for the new thread returned by the
subroutine.
" attr: it species a thread attributes object, or NULL for the default
values.
" start_routine: the C routine that the thread will execute once it is
created.
" arg: 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.
4.67
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
#include <stdio.h>
#include <pthread.h>
main() {
pthread_t f2_thread, f1_thread, f3_thread; int i1=1,i2=2;
void *f2(), *f1(),*f3();
pthread_create(&f1_thread,NULL,f1,&i1);
pthread_create(&f2_thread,NULL,f2,&i2);
pthread_create(&f3_thread,NULL,f3,NULL);
}
void *f1(int *i){
}
void *f2(int *i){
}
void *f3() {
}
4.68
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
pthread_exit()
! When a thread has nished its work, it can exit by calling the
pthread_exit() library procedure
! The thread then vanishes and is no longer schedulable and the stack is
released.
4.69
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Example
void *PrintHello(void *threadid)
{
long tid;
tid = (long) threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0;t<NUM_THREADS;t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
4.70
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Example
void *PrintHello(void *threadid)
{
long tid;
tid = (long) threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0;t<NUM_THREADS;t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(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!
4.71
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Multiple arguments via a structure: example
include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#dene NUM_THREADS 5
char *messages[NUM_THREADS];
struct thread_data
{
int thread_id;
int sum;
char *message;
};
4.72
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
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);
}
4.73
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int *taskids[NUM_THREADS];
int rc, t, sum =0;
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);
}
4.74
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
pthread_join()
! In some thread systems, one thread can wait for a (specic) thread to exit
by calling the pthread_join() procedure
! This procedure blocks the calling thread until (a specic) thread has exited
! The thread identier of the thread to wait for is given as a parameter.
4.75
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Joinable or not?
! When a thread is created, one of its attributes denes whether it is joinable or
detached.
" Only threads that are created as joinable can be joined.
" If a thread is created as detached, it can never be joined.
! Dene and initialize attribute object:
pthread_attr_t attr;
printf("sum = %d\n",sum);
}
4.81
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
/**
* The thread will begin control in this function
*/
if (upper > 0) {
for (i = 1; i <= upper; i++)
sum += i;
}
pthread_exit(0);
}
4.82
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Example of Threads Accessing
Another Threads Stack
char **ptr; /* global */
int main()
{
int i;
pthread_t tid;
char *msgs[N] = {
"Messagge 1",
"Messagge 2"
};
ptr = msgs;
for (i = 0; i < 2; i++)
Pthread_create(&tid,
NULL,
thread,
(void *)i);
Pthread_exit(NULL);
}
/* thread routine */
void *thread(void *vargp)
{
int myid = (int)vargp;
static int svar = 0;
printf("[%d]: %s (svar=%d)\n",
myid, ptr[myid], ++svar);
}
Peer threads access main threads stack
indirectly through global ptr variable
4.83
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Mapping Vars to Mem. Instances
char **ptr; /* global */
int main()
{
int i;
pthread_t tid;
char *msgs[N] = {
"Messagge 1",
"Messagge 2"
};
ptr = msgs;
for (i = 0; i < 2; i++)
Pthread_create(&tid,
NULL,
thread,
(void *)i);
Pthread_exit(NULL);
}
/* thread routine */
void *thread(void *vargp)
{
int myid = (int)vargp;
static int svar = 0;
printf("[%d]: %s (svar=%d)\n",
myid, ptr[myid], ++svar);
}
Global var: 1 instance (ptr [data])
Local static var: 1 instance (svar [data])
Local automatic vars: 1 instance (i.m, msgs.m )
Local automatic var: 2 instances (
myid.p0[peer thread 0s stack],
myid.p1[peer thread 1s stack]
)
4.84
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Shared Variable Analysis
! Which variables are shared?
Variable Referenced by Referenced by Referenced by
instance main thread? peer thread 0? peer thread 1?
ptr yes yes yes
svar no yes yes
i.m yes no no
msgs.m yes yes yes
myid.p0 no yes no
myid.p1 no no yes
! Answer: A variable x is shared if multiple threads reference at least one
instance of x. Thus:
" ptr, svar, and msgs are shared.
" i and myid are NOT shared.
4.85
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
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.
4.86
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Thread Cancellation
! Terminating a thread before it has completed. This case is called target thread.
The pthread_cancel(thread) function requests that thread be canceled
! Cancelability state determines whether a thread can receive a cancellation
request. If the cancelability state is disabled, the thread does not receive any
cancellation requests. The current thread's cancelability state can be changed
by calling pthread_setcancelstate()
! Two approaches (types) (the current thread's cancelability type can be changed
by calling pthread_setcanceltype()):
" Asynchronous cancellation terminates the target thread immediately.
If you set a thread's cancelability type to asynchronous, the thread can
receive a cancellation request at any time.
" Deferred cancellation allows the target thread to periodically check if it
should be cancelled
If you set a thread's cancelability type to deferred, cancellation requests are
acted on as soon as the thread reaches a cancellation point
pthread_testcancel() creates a cancellation point in the calling
thread.
4.87
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Signal
! A signal is a software notication to a process of an event
" Signal is generated when the event that causes the signal occurs
" Signal is delivered when the process takes action based on the signal
" The lifetime of a signal is the interval between its generation and
delivery
" Signal that has been generated but not yet delivered is pending
" Process catches signal if it executes signal handler when the signal is
delivered
" Alternatively, a process can ignore a signal when it is delivered, that is
to take no action
" Process can temporarily prevent signal from being delivered by blocking
it
" Signal Mask contains a set of signals currently blocked.
4.88
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Signal
! Signals are used in UNIX systems to notify a process that a
particular event has occurred
! Examples:
" Typing certain key combinations at the terminal of a running
process causes the system to send it certain signals:
" CTRL-C sends an INT signal (SIGINT); by default, this causes
the process to terminate.
" CTRL-Z sends a TSTP signal (SIGTSTP); by default, this
causes the process to suspend execution.
" CTRL-\ sends a QUIT signal (SIGQUIT); by default, this causes
the process to terminate and store the content of the memory
(core dump).
4.89
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Actions Performed upon Receiving a Signal
! There are three ways in which a process can respond to a signal:
" Explicitly ignore the signal.
" Execute the default action associated with the signal.
" Catch the signal by invoking a corresponding signal-handler function.
! OS signal system call
" To ignore: signal(SIG#, SIG_IGN)
" To reinstate default: signal(SIG#, SIG_DFL)
" To catch: signal(SIG#, myHandler)
! OS provides a facility for writing your own event handlers in the style of
interrupt handlers.
4.90
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Signal Handler
! A signal handler is used to process signals
1. Signal is generated by particular event
2. Signal is delivered to a process
3. Signal is handled
! Corresponding to each signal there is a signal handler
! Called when a process receives a signal
! The function is called asynchronously
! When the signal handler returns the process continues, as if it was never
interrupted
! Signal are different from interrupts as:
" Interrupts are sent to OS by H/W
" Signals are sent to a process by the OS, or by other processes
" Note that signals have nothing to do with software interrupts, which are still
sent by the hardware (the CPU itself, in this case).
4.91
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Signal Generated
Process
Signal Handler
Signal delivered
Signal not blocked
Signal Caught by handler
Return from Signal Handler
Process Resumed
Signal
Mask
Signal
Mask
Signal
Mask
4.92
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Example
#include <stdio.h>
#include <signal.h>
void sigproc()
{
signal(SIGINT, sigproc); /* NOTE some versions of UNIX will reset
* signal to default after each call. So for
* portability reset signal each time */
printf(you have pressed ctrl-c - disabled \n);
}
void quitproc()
{
printf(ctrl-\\ pressed to quit\n); /* this is ctrl & \ */
exit(0); /* normal exit status */
}
main()
{
signal(SIGINT, sigproc); /* ctrl-c : DEFAULT ACTION: term */
signal(SIGQUIT, quitproc); /* ctrl-\ : DEFAULT ACTION: term */
printf(ctrl-c disabled use ctrl-\\ to quit\n);
for(;;);
}
4.93
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Examples of POSIX Required Signals
Signal Description default action
SIGABRT process abort implementation dependent
SIGALRM alarm clock abnormal termination
SIGBUS access undened part of memory object implementation dependent
SIGCHLD child terminated, stopped or continued ignore
SIGILL invalid hardware instruction implementation dependent
SIGINT interactive attention signal (usually ctrl-C) abnormal termination
SIGKILL terminated (cannot be caught or ignored) abnormal termination
4.94
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Signal Description default action
SIGSEGV Invalid memory reference implementation dependent
SIGSTOP Execution stopped stop
SIGTERM termination Abnormal termination
SIGTSTP Terminal stop stop
SIGTTIN Background process attempting read stop
SIGTTOU Background process attempting write stop
SIGURG High bandwidth data available on socket ignore
SIGUSR1 User-dened signal 1 abnormal termination
4.95
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Send a signal
! Raise a signal with kill(pid, signal)
! Posix function: int pthread_kill(pthread_t thread, int sig);
" pid: input parameter, id of the thread to terminate
" sig: signal number
" returns 0 to indicate success, error code otherwise
4.96
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
/* code for process p */
. . .
signal(SIG#, myHndlr);
. . .
/* ARBITRARY CODE */
void myHndlr(...) {
/* ARBITRARY CODE */
}
Signal Handling
4.97
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Signal Handling
/* code for process p */
. . .
signal(SIG#, sig_hndlr);
. . .
/* ARBITRARY CODE */
void sig_hndlr(...) {
/* ARBITRARY CODE */
}
An executing process, q
Raise SIG# for p
sig_hndlr runs in
ps address space
q is blocked
q resumes execution
4.98
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Toy Signal Handler
#include <signal.h>
static void sig_handler(int);
int main () {
int i, parent_pid, child_pid, status;
if(signal(SIGUSR1, sig_handler) == SIG_ERR)
printf(Parent: Unable to create handler for SIGUSR1\n);
if(signal(SIGUSR2, sig_handler) == SIG_ERR)
printf(Parent: Unable to create handler for SIGUSR2\n);
parent_pid = getpid();
if((child_pid = fork()) == 0) {
kill(parent_pid, SIGUSR1);
for (;;) pause();
} else {
kill(child_pid, SIGUSR2);
printf(Parent: Terminating child \n);
kill(child_pid), SIGTERM);
wait(&status);
printf(done\n);
}
}
4.99
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Toy Signal Handler (2)
static void sig_handler(int signo) {
switch(signo) {
case SIGUSR1: /* Incoming SIGUSR1 */
printf(Parent: Received SIGUSER1\n);
break;
case SIGUSR2: /* Incoming SIGUSR2 */
printf(Child: Received SIGUSER2\n);
break;
default: break;
}
return
}
4.100
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
void sighup()
{
signal(SIGHUP,sighup); /* reset signal */
printf("CHILD: I received a SIGHUP\n");
}
void sigint()
{
signal(SIGINT,sigint); /* reset signal */
printf("CHILD: I received a SIGINT\n");
}
void sigquit()
{
printf("My DADDY has Killed me!!!\n");
exit(0);
}
#include <stdio.h>
#include <signal.h>
void sighup();
void sigint();
void sigquit();
main()
{
int pid;
/* get child process */
if ((pid=fork()) < 0)
{ perror("fork"); exit(1); }
if (pid == 0) { /* child */
signal(SIGHUP, sighup);
signal(SIGINT, sigint);
signal(SIGQUIT, sigquit);
for(;;);
} else { /* parent */
printf("\nPARENT: sending SIGHUP\n\n");
kill(pid,SIGHUP);
sleep(3);
printf("\nPARENT: sending SIGINT\n\n");
kill(pid,SIGINT);
sleep(3);
printf("\nPARENT: sending SIGQUIT\n\n");
kill(pid,SIGQUIT);
sleep(3);
}
}
4.101
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Command Line Generates Signals
! You can send a signal to a process from the command line
using kill
! kill l
" will list the signals the system understands
! kill [-signal] pid
" will send a signal to a process.
! The optional argument may be a name or a number.
! The default is SIGTERM.
! To unconditionally kill a process, use:
" kill -9 pid
which is
! kill -SIGKILL pid.
4.102
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
Homework
X
A
=
B C
C[1,1] = A[1,1]*B[1,1]+A[1,2]*B[2,1]..
.
C[m,n]=sum of product of corresponding elements in row of A
and column of B.
Each resultant element can be computed independently.
Let write a program that execute a matrix multiplication
exploiting multithread programming.
4.103
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define M 3
#define K 2
#define N 3
#define NUM_THREADS 10
int A [M][K] = { {1,4}, {2,5}, {3,6} };
int B [K][N] = { {8,7,6}, {5,4,3} };
int C [M][N];
struct v {
int i; /* row */
int j; /* column */
};
void *runner(void *param); /* the thread */
4.104
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
int main(int argc, char *argv[]) {
int i,j, count = 0;
for(i = 0; i < M; i++) {
for(j = 0; j < N; j++) {
//Assign a row and column for each thread
struct v *data = (struct v *) malloc(sizeof(struct v));
data->i = i;
data->j = j;
/* Now create the thread passing it data as a parameter */
pthread_t tid; //Thread ID
pthread_attr_t attr; //Set of thread attributes
//Get the default attributes
pthread_attr_init(&attr);
//Create the thread
pthread_create(&tid,&attr,runner,data);
//Make sure the parent waits for all thread to complete
pthread_join(tid, NULL);
count++;
}
}
4.105
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
//Print out the resulting matrix
for(i = 0; i < M; i++) {
for(j = 0; j < N; j++) {
printf("%d ", C[i][j]);
}
printf("\n");
}
}
4.106
Silberschatz, Galvin and Gagne 2009
Operating System Concepts 8
th
Edition
//The thread will begin control in this function
void *runner(void *param) {
struct v *data = param; // the structure that holds our data
int n, sum = 0; //the counter and sum
//Row multiplied by column
for(n = 0; n< K; n++){
sum += A[data->i][n] * B[n][data->j];
}
//assign the sum to its coordinate
C[data->i][data->j] = sum;
//Exit the thread
pthread_exit(0);
}