62
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Inter Process Communication Modified by M.Rebaudengo - 2013

Inter Process Communication - polito.it · Operating System Concepts – 8 th Edition, Silberschatz, Galvin and Gagne ©2009 Inter Process Communication Modified by M.Rebaudengo -

Embed Size (px)

Citation preview

Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition,

Inter Process Communication

Modified by M.Rebaudengo - 2013

3.2 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Independent vs. cooperating processes

� A process is independent if it cannot be affected by the other processes executing in the system

� A process is cooperating if it can affect or be affected by the other processes executing in the systems� any process that shares data with other processes is a cooperating

process.

3.3 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Interprocess Communication

� Cooperating processes need interprocess communication(IPC) mechanism that will allow them to exchange data andinformation

� Two models of IPC� Shared memory:

a region of memory that is shared by cooperatingprocesses is establishedprocesses can exchange information by reading andwriting data to the shared region

� Message passing:communication takes place by means of messagesexchanged between the cooperating processes.

3.4 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Communications Models

Shared memoryMessage passing

3.5 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Shared memory vs. Message Passing

� Message Passing is � useful for exchanging smaller amounts of data� easier to implement for intercomputer communication

� Shared memory is faster as ...� message passing systems are typically implemented using system calls

and thus require the kernel intervention� in shared-memory systems, systems calls are required only to establish

shared-memory regions and all accesses are treated as classical memory accesses and no assistance from the kernel is required.

3.6 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Shared Memory

Shared memory allows multiple processes to share virtual memory spaceThis is the fastest but not necessarily the easiest way for processes to communicate with one anotherIn general, one process creates or allocates the shared memory segmentThe size and access permissions for the segment are set when it is created The process then attaches the shared segment, causing it to be mapped into its current data spaceIf needed, the creating process then initializes the shared memory.

3.7 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Shared Memory (cont.)

Once created, and if permissions permit, other processes can gain access to the shared memory segment and map it into their data spaceEach process accesses the shared memory relative to its attachment addressWhile the data that these processes are referencing is in common, each process uses different attachment address valuesFor each process involved, the mapped memory appears to be no different from any other of its memory addresses.

3.8 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Shared Memory

Proc. 1 Proc. 2

ptrAttach

Proc. 3 Proc. 4 Proc. 5

ptr ptr ptr

ptrAttach

Create

Shared Memory(unique key)

0

MAX

3.9 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Creating a Shared Memory Segment in POSIX

The shmget system call is used to create the shared memory segment and generate the associated system data structure or to gain access to an existing segmentThe shared memory segment and the system data structure are identified by a unique shared memory identifier that the shmget system call returns.The shmget system call does not entitle the creating process to actually use the allocated memory: it merely reserves the requested memory. Syntax:

int shmget(key_t key, int size, int shmflg);

A new shared memory segment is created if key has the value IPC_PRIVATEThe argument size determines the size in bytes of the shared memory segment The argument shmflg is used to indicate segment creation conditions and access permissions.

3.10 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Attach a shared memory segment

� shmat is used to attach (map) the referenced shared memory segment intothe calling process's data segment.

� Syntax:� void *shmat(int shmid, const void *shmaddr, int shmflg);� The first argument to shmat, shmid, is a valid shared memory identifier� The second argument, shmaddr, allows the calling process some

flexibility in assigning the location of the shared memory segmentIf a nonzero value is given, shmat uses this as the attachmentaddress for the shared memory segmentIf shmaddr is 0, the system picks the attachment address

� The third argument, shmflg, is used to specify the access permissionsfor the shared memory segment and to request special attachmentconditions, such as an aligned address or a read-only segment

� When shmat is successful, it returns the address of the actualattachment.

� If shmat fails, it returns a value of -1

3.11 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Examples of IPC Systems - POSIX

� POSIX Shared Memory� Process first creates shared memory segmentid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);

� Process wanting access to that shared memory must attach to itshared_memory = (char *) shmat(id, NULL, 0);

� Now the process could write to the shared memorysprintf(shared_memory, "Writing to shared memory");

� When done a process can detach the shared memory from its address space

shmdt(shared_memory);

� destroy a segment (only after that all the attached processes are detached)

shmctl(id, IPC_RMID, 0);

3.12 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example#define SHMSZ 27

main ()

{

int shmid; pid_t pid;

char c;

char *shm, *s;

if ( (shmid = shmget (IPC_PRIVATE, SHMSZ, IPC_CREAT ) < 0)) exit (1);

if (( shm = shmat (shmid,NULL,0) ) == (char *) –1) exit (1) ;

/* fork another process */pid = fork();

3.13 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example (cont.)if (pid < 0) exit(-1);

else if (pid == 0) { /* child process */while (shm[SHMSZ-1] != 'z')

sleep(1);

for (s = shm; *s != NULL ; s++)putchar(*s);

putchar('\n');

exit (0);}

else { /* parent process */s = shm;

for (c = 'a' ; c <= 'z' ; c++)

*s++ = c;

*s = NULL;

wait(NULL);

shmdt(shm);

shmctl(shmid, IPC_RMID, 0);

exit(0);}

}

3.14 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Message Passing

� Message Passing provides a mechanism for processes to communicate and to synchronize their actions without sharing the same address space

� IPC facility provides two operations:� send (message)� receive (message)

� If P and Q wish to communicate, they need to:� establish a communication link between them� exchange messages via send/receive

3.15 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Direct Communication

� Each process that wants to communicate must explicitly name the recipient or sender of the communication:� send (P, message) – send a message to process P� receive(Q, message) – receive a message from process Q

� Properties of communication link� Links are established automatically� A link is associated with exactly one pair of communicating processes� The link may be unidirectional, but it is usually bi-directional

3.16 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Indirect Communication

� Messages are directed and received from mailboxes (also known as ports)

� Primitives are defined as:send(A, message) – send a message to mailbox Areceive(A, message) – receive a message from mailbox A

� A mailbox can be viewed abstractly as an object into which messages can be placed by processes and from which messages can be removed� each mailbox has a unique id� processes can communicate only if they share a mailbox� a communication link may be associated with many processes� each pair of processes may share several communication links� link may be unidirectional or bi-directional

3.17 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Mailbox� A mailbox can be owned either

� by a process: the mailbox is part of the address space of the processwe distinguish between the owner (which can only receive messages through this mailbox) and the user (which can only send messages to the mailbox)When a process that owns a mailbox terminates, the mailbox dissapears and any process that subsequently sends a message to this mailbox must be notified that the mailbox no longer exists.

� or by the operating system: the mailbox is independent and is not attached to any particular process.

The operaring system must provide a mechanism that allows a process to:– create a new mailbox– send and receive messages through mailbox– destroy a mailbox

The process that creates a new mailbox is the initial owner of the mailbox that can receive messages through this mailboxThe ownership and receiving privilege may be passed to other processes through appropriate system calls. This provision could result in multiple receivers for each mailbox.

3.18 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Synchronization

� Message passing may be either blocking or non-blocking� Blocking is considered synchronous

� Blocking send: the sender blocks until the message is received

� Blocking receive: the receiver blocks until a message is available

� Non-blocking is considered asynchronous� Non-blocking send: the sender sends the message and

continues� Non-blocking receive: the receiver receives a valid message

or null

3.19 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Possible combinations

� blocking send and blocking receive (rendez-vous)� non blocking send and blocking receive� non blocking send and non blocking receive.

3.20 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Buffering

� Queue of messages attached to the link; implemented in one of three ways1. Zero capacity – 0 messages

Sender must wait for receiver (rendez-vous)2. Bounded capacity – finite length of n messages

Sender must wait if link full3. Unbounded capacity – infinite length

Sender never waits

3.21 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Unix Pipes� Pipe sets up communication channel between two (related) processes:� Pipes are uni-directional

� They can only transfer data in one direction� both the writer and the reader process of a pipeline execute

concurrently� Read and write are atomic operations� a pipe automatically buffers the output of the writer and

suspends the writer if the pipe gets too full� Similarly, if a pipe is empty, the reader is suspended until

some more output becomes available. � Traditional implementation of pipes uses the file system for storage

� This allows processes to communicate even though they don’t know what processes are at the other end of the pipe

Two processes connected by a pipe

3.22 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Types of Pipes

� There are two kinds of pipes� unnamed pipes� named pipes

� Unnamed pipes are used for communication between a parent process (creating the pipe) and its child, with one process writingand the other process reading

� Named pipes solve this problem: any process can communicate with another using named pipes.

3.23 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Unnamed Pipe: pipe()� An unnamed pipe is a unidirectional communications link that

automatically buffers its and may be created using the “pipe()” system call

� Each end of a pipe has an associated file descriptor:� the writer uses the “write” end of the pipe (using “write()”)� the reader uses the “read” end of the pipe (using “read()”).

� int pipe( int fd[2] )“pipe()” creates an unnamed pipe and returns two file descriptors: � the descriptor associated with the “read” end of the pipe is stored

in fd[0]� the descriptor associated with the “write” end of the pipe is

stored in fd[1]� Return value: If the kernel cannot allocate enough space for a

new pipe, “pipe()” returns a value of -1; otherwise, it returns a value of 0.

3.24 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Pipe

� Assume that the following code was executed: int fd[2]; pipe(fd);

The following data structure would be created

fd[0]

fd[1]

� The maximum size of the pipe varies with different versions of UNIX, but is approximately 5K.

PipeWrite end

Read end

3.25 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Close(), Read() and Write()

� When a process has finished with a pipe’s file descriptor it should close it using “close()”.

� Read:� If a process reads from a pipe whose “write” end has been

closed, the “read()” call returns a value of zero, indicating the end of input

� If a process reads from an empty pipe whose “write” end is still open, it sleeps until some input becomes available

� Write:� If a process writes to a pipe whose “read” end has been closed,

the write fails and the writer

� is sent a SIGPIPE signal.

3.26 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Scheme

� The typical sequence of events for a communication is as follows:� The parent process creates an unnamed pipe using “pipe()”� The parent process forks� The processes communicate by using “write()” and “read()”

calls� Each process closes its active pipe descriptor when it’s finished

with it.

3.27 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example

$ cat talk.c ---> list the program.

#include <stdio.h>

#define READ 0 /* The index of the “read” end of the pipe */

#define WRITE 1 /* The index of the “write” end of the pipe */

char* phrase ="This is a message!!!";

main()

{

int fd[2], bytesRead;

char message[100]; /* Parent process’ message buffer */

pipe(fd); /* Create an unnamed pipe */

3.28 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example (cont.)if ( fork() == 0 ) /* Child, write */

{

write(fd[WRITE], phrase, strlen(phrase)+1); /* Send */

close(fd[WRITE]); /* Close used end */

}

else /* Parent, reader */

{

bytesRead = read( fd[READ], message, 100 ); /* Receive */

printf(“Read %d bytes: %s \n”, bytesRead, message );

close(fd[READ]); /* Close used end */

}

}

$ talk ---> run the program.

Read 21 bytes: This is a message!!!"

3.29 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Named Pipes

� Named pipes, often referred to as FIFOs( first in, first out ), are less restricted than unnamed pipes and offer the following advantages:� they have a name that exists in the file system� they may be used by unrelated processes� they exist until explicitly deleted� have a larger buffer capacity, typically about 40K.

� Like an unnamed pipe, a named pipe is intended only for use as a unidirectional link.

� Named pipes exist as special files in the file system and may be created in one of two ways:� by using the UNIX mknod utility (omitted in this presentation)� by using the “mknod()” system call

3.30 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

mknod()

“mknod()” allows you to create a special file:

int mknod( const char* fileName, mode_t type, dev_t device)

“mknod()” creates a new regular, directory, or special file called fileName whose type can be one of the following: VALUE MEANINGS_IFDIR directory S_IFCHR character-oriented file S_IFBLK block-oriented file S_IFREG regular file S_IFIFO named pipe� the parameter device is ignored in case of S_IFIFO type.� “mknod()” returns a value of -1 if unsuccessful and a value of 0

otherwise.

3.31 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Changing mode

� The mode of the pipe can be changed using “chmod()”. � C code that creates a name pipe with read and write permissions

for the owner and group:

mknod(“myPipe”, SIFIFO, 0); /* Create a named pipe */ chmod(“myPipe”, 0660); /* Modify its permission flags */

� A named pipe is, first, opened using “open()”, then

� “write()” adds data at the start of the FIFO queue, and “read()”removes data from the end of the FIFO queue.

3.32 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Close and remove a pipe

� When a process has finished using a named pipe, it should close it using “close()”

� when a named pipe is no longer needed, it should be removed from the file system using “unlink()”.

� Writer processes should open a named pipe for writing only, and reader processes should open a pipe for reading only.

3.33 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example

� A single reader process that creates a named pipe called “aPipe”is executed.

� It then reads and displays NULL-terminated lines from the pipe until the pipe is closed by all of the writing processes.

� One or more writer processes are executed, each of which opens the named pipe called “aPipe” and sends three messages to it.

� If the pipe does not exist when a writer tries to open it, the writer retries every second until it succeeds.

� When all of a writer’s messages are sent, the writer closes the pipe and exits.

3.34 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Reader Program#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> /* For SIFIFO */#include <fcntl.h>

main() { int fd;char str[100];

mknod(“aPipe”, S_IFIFO, 0); /* Create name pipe */

chmod(“aPipe”, 0660); /* Change its permissions */

fd = open(“aPipe”, O_RDONLY); /* Open it for reading */ while(readLine(fd, str) ); /* Display received messages */

printf(“%s\n”, str); close(fd); /* Close pipe */

unlink(“aPipe”); /* Remove named pipe */

}

3.35 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Reader Program (cont.)int readLine( int fd, char* str ) /* Read s single NULL-terminated line into str from fd */ /* Return 0 when the end of input is reached and 1 otherwise */{ int n;

do /* Read characters until NULL or end of input */ {

n = read( fd, str, 1); /* Read one character */}

while ( n>0 && *str++ != NULL );

return ( n > 0 ); /* Return false if end of input */}

3.36 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Writer Program#include <stdio.h> #include <fcntl.h> main()

{ int fd, messageLen, i; char message[100];

/* Prepare message */sprintf( message, “Hello from PID %d”, getpid() ); messageLen = strlen( message ) +1; do /* Keep trying to open the file until successful */{

fd = open( “aPipe”, O_WRONLY ); /*Open named pipe for writing */

if ( fd == -1 ) sleep(1); /* Try again in 1 second */} while ( fd == -1 ); for ( i=1; i<=3; i++) /* Send three messages */

{ write( fd, message, messageLen ); /* Write message down pipe */sleep(3); /* Pause a while */}

close(fd); /* Close pipe descriptor */}

3.37 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Sample Output

$ reader & writer & writer & ---> start 1 reader, 2 writers.[1] 4698 ---> reader process.[2] 4699 ---> first writer process.[3] 4700 ---> second writer process.Hello from PID 4699 Hello from PID 4700Hello from PID 4699 Hello from PID 4700 Hello from PID 4699 Hello from PID 4700 [2] Done writer ---> first writer exists.[3] Done writer ---> second writer exists.[4] Done reader ---> reader exists.$ _

3.38 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Unix Signals� A signal is an asynchronous event which is delivered to a process.

� A UNIX signal corresponds to an event� It is raised by one process (or hardware) to call another

process’s attention to an event� It can be caught (or ignored) by the subject process

� Justification for including signals was for the OS to inform a user process of an event� User pressed delete key

� Program tried to divide by zero� Attempt to write to a nonexistent pipe� etc.

3.39 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Signals

The OS can communicate to an application process through Signals

User Process

Operating System

signals systems calls

3.40 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

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).

3.41 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Exactly what happens when you

� Type Ctrl-c?� Keyboard sends hardware interrupt� Hardware interrupt is handled by OS� OS sends a 2/SIGINT signal

� Type Ctrl-z?� Keyboard sends hardware interrupt� Hardware interrupt is handled by OS� OS sends a 20/SIGTSTP signal

� Issue a “kill –sig pid” command?� OS sends a sig signal to the process whose id is pid

3.42 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Signal� A signal is a software notification to a process of an event:

1. Signal is generated by particular event2. Signal is delivered to a process3. Signal is handled

� Signal is generated when the event that causes the signal occurs� Signal is delivered when the process takes action based on the signal� Then the following 3 options are possible:

Process catches signal if it executes signal handler when the signal is delivereda 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.

3.43 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th 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.

3.44 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Definition of Signal

Signal: A notification of an event� Event gains attention of the OS� OS stops the application process immediately, sending it a signal� Default action for that signal executes

Can install a signal handler to change action� Application process resumes where it left off

movlpushlcall faddlmovl...

Process

void handler(int iSig){…}

signal

3.45 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Examples of Signals

User types Ctrl-c� Event gains attention of OS� OS stops the application process immediately, sending it a 2/SIGINT

signal� Default action for 2/SIGINT signal is “terminate”

Process makes illegal memory reference� Event gains attention of OS� OS stops application process immediately, sending it a 11/SIGSEGV

signal� Default action for 11/SIGSEGV signal is “terminate”

3.46 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Signal Handler

� A signal handler is used to process signals� 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).

3.47 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

An executing process, qq raises “SIG#” for “p”

sig_hndlr runs inp’s address space

q is blocked

q resumes execution

/* code for process p */. . .signal(SIG#, sig_hndlr);. . ./* ARBITRARY CODE */

3.48 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Send a signal

� Raise a signal with kill(pid, signal)� pid: input parameter, id of the thread that receives the signal

� signal: signal number

� returns 0 to indicate success, error code otherwise

� Examplepid_t iPid = getpid(); /* Process gets its id.*/

kill(iPid, SIGINT); /* Process sends itself a SIGINT

signal (commits suicide) */

3.49 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Handling Signals

� Each signal type has a default action� For most signal types, default action is “terminate”

� A program can install a signal handler to change action of (almost) any signal type.

� Special cases: A program cannot install a signal handler for signals of type:� 9/SIGKILL

Default action is “terminate”Catchable termination signal is 15/SIGTERM

� 19/SIGSTOPDefault action is “stop until next 18/SIGCONT”Catchable suspension signal is 20/SIGTSTP

3.50 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

/* code for process p */. . .signal(SIG#, myHndlr);. . .

/* ARBITRARY CODE */

void myHndlr(...) {/* ARBITRARY CODE */

}

Signal Handling

3.51 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example 1#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(;;);}

3.52 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example 2int main( int argc, char *argv[], char *env[] ){ pid_t child_pid, p;

if((child_pid = fork()) == 0 ){

printf("Child(pid=%d): I will send SIGINT to my parent (Pid=%d) and loop forever\n",getpid(), getppid());

kill(getppid(), SIGINT); /* send interrupt signal to parent */

}else /* parent */{

printf("Parent(pid=%d): I will loop forever until I die \n", getpid());

for(;;);}return 0;

}

3.53 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example 3

int main(){ int pid;

printf("alarm application starting\n");if((pid = fork()) == 0) {

sleep(5);kill(getppid(), SIGALRM);exit(0);

}printf("waiting for alarm to go off\n");signal(SIGALRM, ding);pause();printf("done\n");exit(0);

}

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

void ding (int sig){ printf("alarm has gone off\n");}

pause system callcauses program to suspend until a signalis received

3.54 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Note

� Problem with signals:� can cause race conditions

� example: call a pause to wait for a signal� if signal occurs before the call to pause then your program may

wait indefinitely.

3.55 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Example 4void 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);

}}

3.56 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

alarm()

� provides a mechanism for a process to interrupt itself at some future time. It does it by setting a timer; when the timer expires, the process receives a signal.

� Set an alarm timer that will ‘ring’ after a specified number of seconds� a SIGALRM signal is generated

� #include <unistd.h>long alarm(long secs);

� Example:alarm (10); // the process will get SIGALRM signal after 10 (real-time) seconds

3.57 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th 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.

3.58 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Additional Slides

� The following slides are inserted for the sake of completeness.

3.59 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Named Pipes

� To create a named pipe using mknod, use the “p” option.

� The mode of the named pipe may be set using chmod, allowing others to access the pipe that you create.

Here’s an example of this procedure:

$ mknod myPipe p ---> create pipe.$ chmod ug+rw myPipe ---> update permissions.$ ls -lg myPipe ---> examine attributes.prw-rw---- 1 glass cs 0 Feb 27 12:38 myPipe$ _

3.60 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Named pipes� If a process tries to open a named pipe for reading only and no

process currently has it open for writing, the reader will wait until a process opens it for writing, unless O_NONBLOCK or O_NDELAY is set, in which case “open()” succeeds immediately

� If a process tries to open a named pipe for writing only and no process currently has it open for reading, the writer will wait until a process opens it for reading, unless O_NONBLOCK or O_NDELAY is set, in which case “open()” fails immediately.

� In other words: � If O_NDELAY or O_NONBLOCK is set:

an open for reading-only will return without delayan open for writing-only will return an error if no process currently has the file open for reading

� If O_NDELAY and O_NONBLOCK are clear: an open for reading-only will block until a process opens the file for writing an open for writing-only will block until a process opens the file for reading.

3.61 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition

Examples of POSIX Required Signals

Signal Description default action

SIGABRT process abort implementation dependent

SIGALRM alarm clock abnormal termination

SIGBUS access undefined 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

3.62 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th 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-defined signal 1 abnormal termination