Top Banner

of 82

UNIX Inter Process Communications (I)

Apr 07, 2018

Download

Documents

Roopa Kumaar
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • 8/4/2019 UNIX Inter Process Communications (I)

    1/82

    UNIX InterprocessCommunications (I)

  • 8/4/2019 UNIX Inter Process Communications (I)

    2/82

    Outline

    IPC fundamentals

    Pipe FIFO

    Message queue

  • 8/4/2019 UNIX Inter Process Communications (I)

    3/82

    IPC Fundamentals

    What is IPC?

    Mechanisms to transfer data between processes Why is it needed?

    Not all important procedures can be easily built ina single process

  • 8/4/2019 UNIX Inter Process Communications (I)

    4/82

    Why do processes communicate?

    To share resources

    Client/server paradigms Inherently distributed applications

    Reusable software components

    Other good software engineering reasons

  • 8/4/2019 UNIX Inter Process Communications (I)

    5/82

    The Basic Concept of IPC

    A sending process needs to communicate

    data to a receiving process Sender wants to avoid details of receivers

    condition

    Receiver wants to get the data in an

    organized way

  • 8/4/2019 UNIX Inter Process Communications (I)

    6/82

    IPC from the OS Point of View

    OS address space

    Process A Process B

    Privateaddressspace

    Privateaddressspace

  • 8/4/2019 UNIX Inter Process Communications (I)

    7/82

    Fundamental IPC Problem for the OS

    Each process has a private address space

    Normally, no process can write to anotherprocesss space

    How to get important data from process A toprocess B?

  • 8/4/2019 UNIX Inter Process Communications (I)

    8/82

    OS Solutions to IPC Problem

    Fundamentally, two options

    1. Support some form of shared addressspace

    Shared memory

    2. Use OS mechanisms to transport data from

    one address space to another Files, messages, pipes, RPC

  • 8/4/2019 UNIX Inter Process Communications (I)

    9/82

    Fundamental Differences in OS

    Treatment of IPC Solutions

    Shared memory

    OS has job of setting it up And perhaps synchronizing

    But not transporting data

    Messages, etc

    OS involved in every IPC

    Os transports data

  • 8/4/2019 UNIX Inter Process Communications (I)

    10/82

    Desirable IPC Characteristics

    Fast

    Easy to use Well defined synchronization model

    Versatile

    Easy to implement Works remotely

  • 8/4/2019 UNIX Inter Process Communications (I)

    11/82

    IPC and Synchronization

    Synchronization is a major concern for IPC

    Allowing sender to indicate when data istransmitted

    Allowing receiver to know when data is ready

    Allowing both to know when more IPC is possible

  • 8/4/2019 UNIX Inter Process Communications (I)

    12/82

    IPC and Connections

    IPC mechanisms can be connectionless or

    require connection Connectionless IPC mechanisms require no

    preliminary setup

    Connection IPC mechanisms require

    negotiation and setup before data flows Sometimes much is concealed from user, though

  • 8/4/2019 UNIX Inter Process Communications (I)

    13/82

    Connectionless IPC

    Data simply flows

    Typically, no permanent data structuresshared in OS by sender and receiver

    + Good for quick, short communication

    + less long-term OS overhead

    - Less efficient for large, frequentcommunications

    - Each communication takes more OS

    resources per byte

  • 8/4/2019 UNIX Inter Process Communications (I)

    14/82

    Connection-Oriented IPC

    Sender and receiver pre-arrange IPC

    delivery details OS typically saves IPC-related information

    for them

    Advantages/disadvantages pretty much the

    opposites of connectionless IPC

  • 8/4/2019 UNIX Inter Process Communications (I)

    15/82

    Basic IPC Mechanisms

    File system IPC

    Message-based IPC Procedure call IPC

    Shared memory IPC

  • 8/4/2019 UNIX Inter Process Communications (I)

    16/82

    IPC Through the File System

    Sender writes to a file

    Receiver reads from it But when does the receiver do the read?

    Often synchronized with file locking or lock files

    Special types of files can make file-basedIPC easier

  • 8/4/2019 UNIX Inter Process Communications (I)

    17/82

    File IPC Diagram

    Process A Process BData

  • 8/4/2019 UNIX Inter Process Communications (I)

    18/82

    Message-Based IPC

    Sender formats data into a formal message

    With some form of address for receiver OS delivers message to receivers message

    input queue (might signal too)

    Receiver (when ready) reads a message

    from the queue

    Sender might or might not block

  • 8/4/2019 UNIX Inter Process Communications (I)

    19/82

    Message-Based IPC Diagram

    Process A Process BData sentfrom A to B

    OS

    Bs messagequeue

  • 8/4/2019 UNIX Inter Process Communications (I)

    20/82

    Procedure Call IPC

    Interprocess communication uses same

    procedure call interface as intraprocess Data passed as parameters Information returned via return values

    Complicated since destination procedure is

    in a different address space Generally, calling procedure blocks till call

    returns

  • 8/4/2019 UNIX Inter Process Communications (I)

    21/82

    File IPC Diagram

    Process A Process B

    Data as parametersmain () {

    .call();

    .

    .

    .

    }

    .

    ..server();...Data as return values

  • 8/4/2019 UNIX Inter Process Communications (I)

    22/82

    Shared Memory IPC

    Different processes share a common piece

    of memory Either physically or virtually

    Communications via normal reads/writes

    May need semaphores or locks

    In or associated with the shared memory

  • 8/4/2019 UNIX Inter Process Communications (I)

    23/82

    Shared Memory IPC Diagram

    Process A Process B

    write variable x

    main () {

    .x = 10

    .

    .

    .

    }

    .

    ..print(x);...

    read variable x

    x: 10

  • 8/4/2019 UNIX Inter Process Communications (I)

    24/82

    Synchronizing in IPC

    How do sending and receiving process

    synchronize their communications? Many possibilities

    Based on which process block when

    Examples that follow in message context, but

    more generally applicable

  • 8/4/2019 UNIX Inter Process Communications (I)

    25/82

    Blocking Send, Blocking Receive

    Both sender and receiver block

    Sender blocks till receiver receives Receiver blocks until sender sends

    Often called message rendezvous

  • 8/4/2019 UNIX Inter Process Communications (I)

    26/82

    Non-Blocking Send, Blocking Receive

    Sender issues send, can proceed without

    waiting to discover fate of message Receiver waits for message arrival before

    proceeding

    Essentially, receiver is message-driven

  • 8/4/2019 UNIX Inter Process Communications (I)

    27/82

    Non-Blocking Send, Non-Blocking

    Receive

    Neither party blocks

    Sender proceeds after sending message Receiver works until message arrvies

    Either receiver periodically checks in non-blockingfashion

    Or some form of interrupt delivered

  • 8/4/2019 UNIX Inter Process Communications (I)

    28/82

    Addressing in IPC

    How does the sender specify where the datagoes?

    In some cases, the mechanism makes itexplicit (e.g., shared memory and RPC)

    In others, there are options

  • 8/4/2019 UNIX Inter Process Communications (I)

    29/82

    Direct Addressing

    Sender specifies name of the receivingprocess

    Using some form of unique process name

    Receiver can either specify name ofexpected sender

    Or take stuff from anyone

  • 8/4/2019 UNIX Inter Process Communications (I)

    30/82

    Indirect Addressing

    Data is sent to queues, mailboxes, or someother form of shared data structure

    Receiver performs some form of readoperations on that structure

    Much more flexible than direct addressing

  • 8/4/2019 UNIX Inter Process Communications (I)

    31/82

    Duality in IPC Mechanisms

    Many aspects of IPC mechanisms are dualsof each other

    Which implies that these mechanisms havethe same power

    First recognized in context of messages vs.

    procedure calls At least, IPC mechanisms can be simulated

    by each other

  • 8/4/2019 UNIX Inter Process Communications (I)

    32/82

    So which IPC mechanism to

    build/choose/use?

    Depends on model of computation

    And on philosophy of user In particular cases, hardware or existing

    software may make one perform better

  • 8/4/2019 UNIX Inter Process Communications (I)

    33/82

    Typical UNIX IPC Mechanisms

    Different versions of UNIX introduceddifferent IPC mechanisms

    Pipes

    Message queues

    Semaphores

    Shared memory Sockets

    RPC

  • 8/4/2019 UNIX Inter Process Communications (I)

    34/82

    Pipes

    Only IPC mechanism in early UNIX systems (otherthan files) Uni-directional

    Unformatted

    Uninterpreted

    Interprocess byte streams

    Accessed in file-like way Only used for parent-child or sib process pairs

  • 8/4/2019 UNIX Inter Process Communications (I)

    35/82

    Pipe Details

    One process feeds bytes into pipe

    A second process reads the bytes from it Potentially blocking communication

    mechanism

    Requires close cooperation betweenprocesses to set up Named pipes allow more flexibility

  • 8/4/2019 UNIX Inter Process Communications (I)

    36/82

    Pipes and Blocking

    Writing more bytes than pipe capacity blocksthe sender

    Until the receiver reads some of them

    Reading bytes when none are availableblocks the receiver

    Until the sender writes some

    Single pipe cant cause deadlock

  • 8/4/2019 UNIX Inter Process Communications (I)

    37/82

    Piping in a C program:

    Piping is a process where the input of one process ismade the input of another. We have seen examples

    of this from the UNIX command line using | We will now see how we do this from C programs

    We will have two (or more) forked processes and willcommunicate between them

    UNIX allows two ways of opening a pipe

  • 8/4/2019 UNIX Inter Process Communications (I)

    38/82

    popen() -- Formatted Piping

    FILE *popen(char *command, char *type) -- opens a pipe forI/O where the command is the process that will be connected tothe calling process thus creating the pipe. The type is either ``r''

    - for reading, or ``w'' for writing

    popen() returns is a stream pointer or NULL for any errors

    A pipe opened by popen() should always be closed bypclose(FILE *stream)

    We use write() and read() to communicate with the pipe'sstream

  • 8/4/2019 UNIX Inter Process Communications (I)

    39/82

    Reading Output From an External Program#include #include #include #include

    int main(){

    FILE *read_fp;char buffer[BUFSIZ + 1];int chars_read;memset(buffer,\0,sizeof(buffer));read_fp = popen(uname a, r);if (read_fp !=NULL){

    chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);if (chars_read > 0){

    printf(Output was:-\n%s\n,buffer);}

    pclose(read_fp);exit(EXIT_SUCCESS);}exit(EXIT_FAILURE);

    }

  • 8/4/2019 UNIX Inter Process Communications (I)

    40/82

    Sending Output to popen

    #include #include #include

    int main(){FILE *write_fp;char buffer[BUFSIZ + 1];sprintf(buffer, Once upon a time, there was \n);write_fp = popen (od c, w);if (write_fp != NULL){

    fwrite( buffer , sizeof(char), strlen(buffer), write_fp);pclose(write_fp);exit(EXIT_SUCCESS);

    }exit(EXIT_FAILURE);

    }

  • 8/4/2019 UNIX Inter Process Communications (I)

    41/82

    pipe() -- Low level Piping

    int pipe(int fd[2]) -- creates a pipe and returns two filedescriptors, fd[0], fd[1]

    fd[0] is opened for reading, fd[1] for writing pipe() returns 0 on success, -1 on failure and sets errno

    accordingly

    The standard programming model is that after the pipe hasbeen set up, two (or more) cooperative processes will be

    created by a fork and data will be passed using read() andwrite()

    Pipes opened with pipe() should be closed with close(intfd )

  • 8/4/2019 UNIX Inter Process Communications (I)

    42/82

    The pipe Function

    #include

    #include #include #include Int main(){

    int data_processed;int file_pipes[2];const char some_data[] = 123

    char buffer[BUFSIZ + 1];

    memset(buffer, \0, sizeof(buffer));if (pipe(file_pipes) == 0){

    data_processed = write(file_pipes[1], some_data, strlen(some_data));printf(Wrote %d bytes\n, data_processed);data_processed = read(file_pipes[0], buffer, BUFSIZ);printf(Read %d bytes: %s

    \n, data_processed, buffer);

    exit(EXIT_SUCCESS);}exit (EXIT_FAILURE);

    }

  • 8/4/2019 UNIX Inter Process Communications (I)

    43/82

    Example: Parent writes to a child

    int pdes[2];

    pipe(pdes);

    if ( fork() == 0 ){ /* child */

    close(pdes[1]); /* not required */read( pdes[0]); /* read from parent */.....

    }

    else

    { close(pdes[0]); /* not required */write( pdes[1]); /* write to child */.....

    }

  • 8/4/2019 UNIX Inter Process Communications (I)

    44/82

    #include

    #include

    #include

    #include

    int pdes[2];char string[128];

    char string2[] = "This msg is ent to child process";

    main(){

    pipe(pdes);

    if(fork()==0){

    close(pdes[1]);

    read(pdes[0],string,128);printf("The msg recieved from parent process:\n");

    printf("%s\n",string);

    }

    else{

    close(pdes[0]);

    write(pdes[1],string2,strlen(string2));

    }}

  • 8/4/2019 UNIX Inter Process Communications (I)

    45/82

    Named Pipes: FIFOs

    So far, we have only been able to pass data between programsthat are related, i.e. programs that have been started from a

    common ancestor process. We would like unrelated processesto be able to exchange data

    We do this with FIFOs, often referred to as named pipes

    A named pipe is a special type of file that exists as a name inthe file system, but behaves like the unnamed pipes

  • 8/4/2019 UNIX Inter Process Communications (I)

    46/82

    We can create named pipes from the command line

    $ mkfifo filename

    E.g.

    $ mkfifo fpipe

    $ grep .c < fpipe &

    $ls > fpipe

    From inside a program, we can use the following call:

    #include

    #include

    Int mkfifo(const char *filename, mode_t mode);

  • 8/4/2019 UNIX Inter Process Communications (I)

    47/82

    Creating a Named Pipe#include

    #include #include #incldue #include Int main(){

    int res = mkfifo(/tmp/my_fifo,0777);if (res == 0) printf(FIFO created\n);exit (EXIT_SUCCESS);

    }

    We can look for the pipe in terminal with:$ls -lF /tmp/my_fifo

    prwxr-xr-x 1 macpbook wheel 0 2 Apr 16:32 /tmp/my_fifo|

  • 8/4/2019 UNIX Inter Process Communications (I)

    48/82

    Creating a Named Pipe

    1. First, lets try reading the (empty) FIFO$ cat < /tmp/my_fifo

    2. Now try writing to the FIFO$ echo abcdefg > /tmp/my_fifo

    3. If we do both at once, we can pass information through thepipe:

    $ mkfifo /tmp/my_fifo$ cat < /tmp/my_fifo &[1] 1316$ echo abcdefg > /tmp/my_fifoabcdefg

    [1]+ Done cat < /tmp/my_fifo$

  • 8/4/2019 UNIX Inter Process Communications (I)

    49/82

    Opening a FIFO with open

    The main restriction on opening FIFOs is that a program maynot open a FIFO for reading and writing with the mode

    O_RDWR If we do wish to pass data in both directions between programs,

    its much better to use either a pair of FIFOs or pipes, one foreach direction

    Or (unusually) explicity change the direction of the data flow by

    closing and re-opening the FIFO

  • 8/4/2019 UNIX Inter Process Communications (I)

    50/82

    Opening a FIFO with open

    There are four legal combinations of O_RDONLY, O_WRONLYand the O_NONBLOCK

    A readon an empty blocking FIFO (i.e. one not opened withO_NONBLOCK) will wait until spme data can be read.

    A writeon a full FIFO will wait until the data can be written.

  • 8/4/2019 UNIX Inter Process Communications (I)

    51/82

    open(const char *path, O_RDONLY);

    In this case, the open call will block, I.e. not return until a process opens thesame FIFO for writing

    open(const char *path, O_RDONLY | O_NONBLOCK);

    The open call will now succeed and return immediately, even if the FIFO had notbeen opened for writing by any process

    open(const char *path, O_WRONLY);

    In this case, the open call will block until a process opens the same FIFO forreading

    open(const char *path, O_WRONLY | O_NONBLOCK);

    This will always return immediately, but if not process has the FIFO open forreading, open will return an error, -1, and the FIFO wont be opened. If a process

    does have the FIFO open for reading, the file descriptor returned can be used forwriting to the FIFO

  • 8/4/2019 UNIX Inter Process Communications (I)

    52/82

    Inter-process Communication with FIFOs

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #define FIFO_NAME /tmp/my_file

    #define BUFFER_SIZE PIPE_BUF

    #define TEN_MEG (1024*1024*10)

    Int main()

  • 8/4/2019 UNIX Inter Process Communications (I)

    53/82

    Int main()

    {

    int pipe_fd;

    int res;

    int open_mode = O_WRONLY;

    int bytes_sent = 0;

    char buffer[BUFFER_SIZE + 1];

    if (access(FIFO_NAME, F_OK) == -1){

    res = mkfifo(FIFO_NAME, 0777);

    if (res != 0){

    fprintf(stderr, Could not create fifo %s\n, FIFO_NAME);

    exit(EXIT_FAILURE)

    }

    }

    printf(Process %d opening FIFO O_WRONLY\n,getpid());

    pipe_fd = open(FIFO_NAME, open_mode);

    printf(Process %d result %d\n, getpid(),pipe_fd);

    if (pipe fd ! 1){

  • 8/4/2019 UNIX Inter Process Communications (I)

    54/82

    if (pipe_fd != -1){

    while(bytes_sent < TEN_MEG){

    res = write(pipe_fd, buffer, BUFFER_SIZE);

    if (res == -1){

    fprintf(stderr, Write error on pipe\n);exit(EXIT_FAILURE);

    }

    bytes_sent +=res;

    }

    (void) close(pipe_fd);

    }

    else{

    exit(EXIT_FAILURE);

    }

    printf(Process %d finished\n, getpid());

    exit(EXIT_FAILURE);}

    #include

  • 8/4/2019 UNIX Inter Process Communications (I)

    55/82

    #include

    #include

    #include

    #include

    #include #include

    #include

    #include

    #define FIFO_NAME /tmp/my_fifo

    #define BUFFER_SIZE PIPE_BUF

    Int main()

    {

    int pipe_fd;

    int res;

    int open_mode = O_RDONLY;char buffer(BUFFER_SIZE + 1);

  • 8/4/2019 UNIX Inter Process Communications (I)

    56/82

    int bytes_read = 0;

    memset(buffer, \0, sizeof(buffer));

    printf(Process %d opening FIFO O_RDONLY\n,getpid());

    pipe_fd = open(FIFO_NAME, open_mode);

    printf(Process %d result %d\n, getpid(), pipe_fd);

    if (pipe_fd != -1){

    do{

    res = read(pipe_fd, buffer, BUFFER_SIZE);

    bytes_read += res;

    } while (res > 0);

    (void) close(pipe_fd);

    }

    else{

    exit(EXIT_FAILURE);

    }

    printf(Process %d finished, %d bytes read\n, getpid(), bytes_read);exit(EXIT_SUCCESS);

    }

  • 8/4/2019 UNIX Inter Process Communications (I)

    57/82

    UNIX Message Queues

    Introduced in System V Release 3 UNIX

    Like pipes, but data organized into messages Message component include:

    Type identifier

    Length

    Data

  • 8/4/2019 UNIX Inter Process Communications (I)

    58/82

    What Are Message Queues

    A message queue is a queue onto whichmessages can be placed

    A message is composed of a message type(which is a number), and message data

    A message queue can be either private, or

    public If it is private, it can be accessed only by its

    creating process or child processes of that creator

  • 8/4/2019 UNIX Inter Process Communications (I)

    59/82

    Creating A Message Queue - msgget()

    This system call accepts two parameters - a queuekey, and flags

    The key may be one of: IPC_PRIVATE - used to create a private message queue.

    a positive integer - used to create (or access) a publicly-accessible message queue

    The second parameter contains flags that controlhow the system call is to be processed It may contain flags like IPC_CREAT or IPC_EXCL

  • 8/4/2019 UNIX Inter Process Communications (I)

    60/82

    The lowest 9 bits of the flags are used todefine access permission for the queue,much like similar 9 bits are used to controlaccess to files

    the bits are separated into 3 groups - user, groupand others. In each set, the first bit refers to readpermission, the second bit - to write permission,and the third bit is ignored

  • 8/4/2019 UNIX Inter Process Communications (I)

    61/82

    #include /* standard I/O routines. */#include /* standard system data types. */#include /* common system V IPC structures. */#include /* message-queue specific functions. */

    /* create a private message queue, with access only to the owner. */int queue_id = msgget(IPC_PRIVATE, 0600);

    /*

  • 8/4/2019 UNIX Inter Process Communications (I)

    62/82

    The Message Structure - struct msgbuf

    struct msgbuf

    { long mtype; /* message type, a positivenumber (cannot be zero). */

    char mtext[1]; /* message body array.usually larger than one byte. */

    };

  • 8/4/2019 UNIX Inter Process Communications (I)

    63/82

    /* first, define the message string */char* msg_text = "hello world";

    /* allocate a message with enough space for length of string and *//* one extra byte for the terminating null character. */struct msgbuf* msg = (struct msgbuf*)malloc(sizeof(struct msgbuf)

    + strlen(msg_text));/* set the message type. for example - set it to '1'. */msg->mtype = 1;

    /* finally, place the "hello world" string inside the message. */strcpy(msg->mtext, msg_text);

  • 8/4/2019 UNIX Inter Process Communications (I)

    64/82

    When allocating a space for a string, one always needs toallocate one extra byte for the null character terminating thestring. In our case, we allocated strlen(msg_text) more than the

    size of "struct msgbuf", and didn't need to allocate an extraplace for the null character, cause that's already contained inthe msgbuf structure (the 1 byte of mtext there).

    We don't need to place only text messages in a message. Wemay also place binary data. In that case, we could allocatespace as large as the msgbuf struct plus the size of our binarydata, minus one byte. Of-course then to copy the data to themessage, we'll use a function such as memset(), and notstrcpy().

  • 8/4/2019 UNIX Inter Process Communications (I)

    65/82

    Writing Messages Onto A Queue -

    msgsnd()

    Once we created the message queue, and a messagestructure, we can place it on the message queue, using themsgsnd() system call

    It takes the following parameters: int msqid - id of message queue, as returned from the

    msgget() call. struct msgbuf* msg - a pointer to a properly initializes

    message structure int msgsz - the size of the data part (mtext) of the message,

    in bytes. int msgflg - flags specifying how to send the message.

  • 8/4/2019 UNIX Inter Process Communications (I)

    66/82

    So in order to send our message on thequeue, we'll use msgsnd() like this:

    int rc = msgsnd(queue_id, msg, strlen(msg_text)+1, 0);if (rc == -1) {perror("msgsnd");

    exit(1); }

    Note that we used a message size one larger then the lengthof the string, since we're also sending the null character.

  • 8/4/2019 UNIX Inter Process Communications (I)

    67/82

    Reading A Message From The Queue -

    msgrcv()

    This system call accepts the following list of parameters: int msqid - id of the queue, as returned from msgget(). struct msgbuf* msg - a pointer to a pre-allocated msgbuf structure. It

    should generally be large enough to contain a message with somearbitrary data (see more below). int msgsz - size of largest message text we wish to receive. Must NOT

    be larger then the amount of space we allocated for the message textin 'msg'.

    int msgtyp - Type of message we wish to read. may be one of: 0 - The first message on the queue will be returned.

    a positive integer - the first message on the queue whose type (mtype)equals this integer (unless a certain flag is set in msgflg, see below).

    a negative integer - the first message on the queue whose type is less thanor equal to the absolute value of this integer.

  • 8/4/2019 UNIX Inter Process Communications (I)

    68/82

    int msgflg - a logical 'or' combination of any of thefollowing flags:

    IPC_NOWAIT - if there is no message on the queuematching what we want to read, return '-1

    MSG_EXCEPT - if the message type parameter is apositive integer, then return the first message whose type isNOT equal to the given integer.

    MSG_NOERROR - If a message with a text part larger than'msgsz' matches what we want to read, then truncate thetext when copying the message to our msgbuf structure. Ifthis flag is not set and the message text is too large, thesystem call returns '-1'

  • 8/4/2019 UNIX Inter Process Communications (I)

    69/82

    /* prepare a message structure large enough to

    read our "hello world". */struct msgbuf* recv_msg =(struct msgbuf*)malloc(sizeof(struct msgbuf)+strlen("hello world"));

    /* use msgrcv() to read the message.We agree to get any type, and thus */

    /* use '0' in the message type parameter, and use no flags (0). */

    int rc = msgrcv(queue_id, recv_msg, strlen("hello world")+1, 0, 0);if (rc == -1){ perror("msgrcv");exit(1); }

  • 8/4/2019 UNIX Inter Process Communications (I)

    70/82

    If the message on the queue was larger than thesize of "hello world" (plus one), we would get an

    error, and thus exit. If there was no message on the queue, the

    msgrcv() call would have blocked our process untilone of the following happens:

    a suitable message was placed on the queue.

    the queue was removed (and then errno would be set toEIDRM).

    our process received a signal

  • 8/4/2019 UNIX Inter Process Communications (I)

    71/82

    Process Synchronization WithSemaphores

  • 8/4/2019 UNIX Inter Process Communications (I)

    72/82

    What Is A Semaphore?

    A semaphore is a resource that contains aninteger value, and allows processes to

    synchronize by testing and setting this valuein a single atomic operation

    This means that the process that tests thevalue of a semaphore and sets it to a

    different value (based on the test), isguaranteed no other process will interferewith the operation in the middle.

  • 8/4/2019 UNIX Inter Process Communications (I)

    73/82

    Two types of operations can be carried on asemaphore: wait and signal.

    A set operation first checks if thesemaphore's value equals some number. If it does, it decreases its value and returns.

    If it does not, the operation blocks the callingprocess until the semaphore's value reaches thedesired value.

  • 8/4/2019 UNIX Inter Process Communications (I)

    74/82

    signal operation increments the value of thesemaphore, possibly awakening one or more

    processes that are waiting on the semaphore

    A semaphore set is a structure that stores agroup of semaphores together, and possibly

    allows the process to commit a transactionon part or all of the semaphores in the settogether.

  • 8/4/2019 UNIX Inter Process Communications (I)

    75/82

    Creating A Semaphore Set - semget()

    Similarly to the creation of message queues,we supply some ID for the set, and some

    flags (used to define access permissionmode and a few options).

    We also supply the number of semaphores

    we want to have in the given set

  • 8/4/2019 UNIX Inter Process Communications (I)

    76/82

    /* ID of the semaphore set. */int sem_set_id_1;

    int sem_set_id_2;/* create a private semaphore set with one semaphore in it, *//* with access only to the owner. */sem_set_id_1 = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);if (sem_set_id_1 == -1)

    { perror("main: semget"); exit(1); }

    /* create a semaphore set with ID 250, three semaphores *//* in the set, with access only to the owner. */sem_set_id_2 = semget(250, 3, IPC_CREAT | 0600);if (sem_set_id_2 == -1)

    { perror("main: semget"); exit(1); }

    Setting And Getting Semaphore Values

  • 8/4/2019 UNIX Inter Process Communications (I)

    77/82

    Setting And Getting Semaphore ValuesWith semctl()

    /* use this to store return values of system calls. */int rc;

    /* initialize the first semaphore in our set to '3'. */rc = semctl(sem_set_id_2, 0, SETVAL, 3);if (rc == -1) { perror("main: semctl");exit(1); }

    /* initialize the second semaphore in our set to '6'. */rc = semctl(sem_set_id_2, 1, SETVAL, 6);

    if (rc == -1) { perror("main: semctl"); exit(1); }/* initialize the third semaphore in our set to '0'. */rc = semctl(sem_set_id_2, 2, SETVAL, 0);if (rc == -1) { perror("main: semctl"); exit(1); }

    Using Semaphores For Mutual

  • 8/4/2019 UNIX Inter Process Communications (I)

    78/82

    Using Semaphores For MutualExclusion With semop()

    Sometimes we have a resource that we wantto allow only one process at a time to

    manipulate Example: File operations

  • 8/4/2019 UNIX Inter Process Communications (I)

    79/82

    /* this function updates the contents of the file with the given path name. */void update_file(char* file_path, int number){ /* structure for semaphore operations. */

    struct sembuf sem_op;FILE* file;

    /* wait on the semaphore, unless it's value is non-negative. */sem_op.sem_num = 0;sem_op.sem_op = -1;

    /*

  • 8/4/2019 UNIX Inter Process Communications (I)

    80/82

    Comment 1 - before we access the file, we use semop() to wait onthe semaphore. Supplying '-1' in sem_op.sem_op means: If thevalue of the semaphore is greater then or equal to '1', decrease thisvalue by one, and return to the caller. Otherwise (the value is 1 or

    less), block the calling process, until the value of the semaphorebecomes '1', at which point we return to the caller.

    Comment 2 - The semantics of semop() assure us that when wereturn from this function, the value of the semaphore is 0. Why? itcouldn't be less, or else semop() won't return. It couldn't be more dueto the way we later on signal the semaphore. And why it cannot bemore then '0'? read on to find out...

    Comment 3 - after we are done manipulating the file, we increasethe value of the semaphore by 1, possibly waking up a processwaiting on the semaphore. If several processes are waiting on thesemaphore, the first that got blocked on it is wakened and continuesits execution.

    Using Semaphores For Producer

  • 8/4/2019 UNIX Inter Process Communications (I)

    81/82

    Using Semaphores For Producer-Consumer Operations With semop()

    /* this variable will contain the semaphore set. */int sem_set_id;

    /* semaphore value, for semctl(). */

    union semun sem_val;/* structure for semaphore operations. */struct sembuf sem_op;

    /* first we create a semaphore set with a single semaphore, *//* whose counter is initialized to '0'. */sem_set_id = semget(IPC_PRIVATE, 1, 0600);

    if (sem_set_id == -1) { perror("semget"); exit(1); }sem_val.val = 0;semctl(sem_set_id, 0, SETVAL, sem_val);

  • 8/4/2019 UNIX Inter Process Communications (I)

    82/82

    /* we now do some producing function, and then signal the *//* semaphore, increasing its counter by one. */. . sem_op.sem_num = 0;

    sem_op.sem_op = 1;sem_op.sem_flg = 0;semop(sem_set_id, &sem_op, 1);. . . /* meanwhile, in a different process, we try to consume the */

    /* resource protected (and counter) by the semaphore. *//* we block on the semaphore, unless it's value is non-negative. */

    sem_op.sem_num = 0;sem_op.sem_op = -1;sem_op.sem_flg = 0;semop(sem_set_id, &sem_op, 1);/* when we get here it means that the semaphore's value is '0' */