Lec 20 Semaphores

download Lec 20 Semaphores

of 22

Transcript of Lec 20 Semaphores

  • 8/8/2019 Lec 20 Semaphores

    1/22

    Lecture 20

    Semaphores

    Lecture 20

    SemaphoresTopicsTopics System V IPC: Semaphores

    Semaphore Sets

    November 1, 2005

    CSCE 510 Systems Programming

  • 8/8/2019 Lec 20 Semaphores

    2/22

  • 8/8/2019 Lec 20 Semaphores

    3/22

    3 CSCE 510 Fall 2005

    System V IPC - reviewSystem V IPC - review

    System V IPCSystem V IPC

    ObjectsObjects

    Shared memory segments two program shared a piece of memory

    Msgqueues - a priority queue for messages, guaranteed atomic

    Semaphore sets Sets of semaphores as in CSCE 311

    Each semaphore can control access to another IPC object say shared memory

    segment

    Different from I/O systemDifferent from I/O system special functions for creating, reading,special functions for creating, reading,and writingand writing

  • 8/8/2019 Lec 20 Semaphores

    4/22

    4 CSCE 510 Fall 2005

    MSG_Queues Overview of FunctionsMSG_Queues Overview of Functions

    key_t ftok(const char *pathname, int proj_id);key_t ftok(const char *pathname, int proj_id);

    int msgget(key_t key, int msgflg);int msgget(key_t key, int msgflg);

    Flags perms | IPC_CREAT | IPC_EXCL // to create a new one

    int msgctl(int msqid, int cmd, struct msqid_ds *buf);int msgctl(int msqid, int cmd, struct msqid_ds *buf);

    int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);

    ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, longssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, longmsgmsg--typ, int msgflg);typ, int msgflg);

  • 8/8/2019 Lec 20 Semaphores

    5/22

    5 CSCE 510 Fall 2005

    SemaphoresSemaphores

    E. W. DijkstraE. W. Dijkstra

    P(sem) or wait(sem)P(sem) or wait(sem)

    if( sem != 0)if( sem != 0)

    decrement sem by onedecrement sem by one

    elseelse

    wait until sem becomes nonwait until sem becomes non--zero, then decrementzero, then decrement

    V(sem) or Signal(sem)V(sem) or Signal(sem)increment sem by oneincrement sem by one

    if( queue of waiting processes is not empty)if( queue of waiting processes is not empty)

    restart first process in the wait queuerestart first process in the wait queue

  • 8/8/2019 Lec 20 Semaphores

    6/22

    6 CSCE 510 Fall 2005

    Semaphore InvariantSemaphore Invariant

    The Semaphore Invariant below is always true!The Semaphore Invariant below is always true!

    (semaphores initial value(semaphores initial value

    + number of signal operations+ number of signal operations

    -- number of completed wait operations) >= 0number of completed wait operations) >= 0

    Semaphores can be used for mutual exclusion.Semaphores can be used for mutual exclusion.

  • 8/8/2019 Lec 20 Semaphores

    7/22

    7 CSCE 510 Fall 2005

    Semaphore SetsSemaphore Sets

    FunctionsFunctions

    int semget(key_t key, int nsems, int semflg);int semget(key_t key, int nsems, int semflg);

    int semctl(int semid, int semnum, int cmd, ...);int semctl(int semid, int semnum, int cmd, ...);

    int semop(int semid, struct sembuf *sops, unsigned nsops);int semop(int semid, struct sembuf *sops, unsigned nsops);

  • 8/8/2019 Lec 20 Semaphores

    8/22

    8 CSCE 510 Fall 2005

    Values associated with SemaphoresValues associated with Semaphores

    Associated with each semaphore in the set are the values:Associated with each semaphore in the set are the values:

    SemvalSemval the semaphore value always >= 0the semaphore value always >= 0

    SempidSempid process id of last process to act on semaphoreprocess id of last process to act on semaphore

    SemcntSemcnt number of process waiting for sem to get larger valuenumber of process waiting for sem to get larger value SemzcntSemzcnt number of process waiting for semaphore to be zeronumber of process waiting for semaphore to be zero

  • 8/8/2019 Lec 20 Semaphores

    9/22

    9 CSCE 510 Fall 2005

    int semget();int semget();

    int semget(key_t key, int nsems, int semflg);int semget(key_t key, int nsems, int semflg);

    key_t keykey_t key

    int nsemsint nsems number of semaphores to be in the setnumber of semaphores to be in the set

    int semflgint semflg IPC_CREAT and IPC_EXCL

  • 8/8/2019 Lec 20 Semaphores

    10/22

    10 CSCE 510 Fall 2005

    int semctl(); - Semaphore Controlint semctl(); - Semaphore Control

    int semctl(int semid, int semnum, int cmd, ...);int semctl(int semid, int semnum, int cmd, ...);

    int semidint semid

    int semnumint semnum

    int cmdint cmd

    IPC_STAT stat semaphore data into structure pointed to by arg.buf IPC_SET copy data to semid_ds structure pointed to by arg.buf

    IPC_RMID - Immediately remove the semaphore set and its data structures awakening

    all waiting processes

    More commands on next sldie

    ... Optional fourth argument arg of type semun on upcoming slide... Optional fourth argument arg of type semun on upcoming slide

  • 8/8/2019 Lec 20 Semaphores

    11/22

    11 CSCE 510 Fall 2005

    More Semctl CommandsMore Semctl Commands

    GETALLGETALL -- Return semval for all semaphores of the set intoReturn semval for all semaphores of the set intoarg.arrayarg.array

    GETNCNTGETNCNT -- returns the value of semncnt for the semnumreturns the value of semncnt for the semnum--ththsemaphore of the setsemaphore of the set

    GETPIDGETPID

    GETVALGETVAL -- returns the value of semval for the semnumreturns the value of semval for the semnum--ththsemaphore of the setsemaphore of the set

    GETZCNTGETZCNT -- returns the value of semzcntreturns the value of semzcnt

    SETALLSETALL

    SETVALSETVAL

  • 8/8/2019 Lec 20 Semaphores

    12/22

    12 CSCE 510 Fall 2005

    Semctl Return ValuesSemctl Return Values

    Return values from semctlReturn values from semctl

    GETNCNT the value of semncnt.GETNCNT the value of semncnt.

    GETPID the value of sempid.GETPID the value of sempid.

    GETVAL the value of semval.GETVAL the value of semval. GETZCNT the value of semzcnt.GETZCNT the value of semzcnt.

    All other cmd values return 0 on success.All other cmd values return 0 on success.

    --1 on error and set global value errno1 on error and set global value errno

  • 8/8/2019 Lec 20 Semaphores

    13/22

    13 CSCE 510 Fall 2005

    Semun Data StructureSemun Data Structure

    union semun {union semun {

    int val;int val; /* value for SETVAL *//* value for SETVAL */

    struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */

    unsigned short *array; /* array for GETALL, SETALL */unsigned short *array; /* array for GETALL, SETALL */

    /* Linux specific part: *//* Linux specific part: */

    struct seminfo *__buf; /* buffer for IPC_INFO */struct seminfo *__buf; /* buffer for IPC_INFO */

    };};

  • 8/8/2019 Lec 20 Semaphores

    14/22

    14 CSCE 510 Fall 2005

    /* Structure used for argument to `semop' to describe operations. *//* Structure used for argument to `semop' to describe operations. */

    struct sembufstruct sembuf

    {{

    unsigned short int sem_num; /* semaphore number */unsigned short int sem_num; /* semaphore number */short int sem_op; /* semaphore operation */short int sem_op; /* semaphore operation */

    short int sem_flg; /* operation flag */short int sem_flg; /* operation flag */

    };};

  • 8/8/2019 Lec 20 Semaphores

    15/22

    15 CSCE 510 Fall 2005

    Semop() Semaphore OperationsSemop() Semaphore Operations

    int semop(int semid, struct sembuf *sops, unsigned nsops);int semop(int semid, struct sembuf *sops, unsigned nsops);

    A semaphore is represented by an anonymous structure including theA semaphore is represented by an anonymous structure including thefollowing members:following members:

    unsigned short semval; /* semaphore value */unsigned short semval; /* semaphore value */

    unsigned short semzcnt; /* # waiting for zero */unsigned short semzcnt; /* # waiting for zero */

    unsigned short semncnt; /* # waiting for increase */unsigned short semncnt; /* # waiting for increase */

    pid_t sempid; /* process that did last op */pid_t sempid; /* process that did last op */

  • 8/8/2019 Lec 20 Semaphores

    16/22

    16 CSCE 510 Fall 2005

    SemHeader.hSemHeader.h

    #include #include #include #include

    #include #include

    #include #include

    #define SEMPERM 0600#define SEMPERM 0600

    typedef union {typedef union {

    int val;int val;struct semid_ds *buf;struct semid_ds *buf;

    ushort *array;ushort *array;

    } semun;} semun;

  • 8/8/2019 Lec 20 Semaphores

    17/22

    17 CSCE 510 Fall 2005

    InitSemInitSem

    int initsem( key_t semkey)int initsem( key_t semkey){{

    int status = 0;int status = 0;

    int semid;int semid;

    if((semid = semget(semkey, 1, SEMPERM | IPC_CREAT| IPC_EXCL)) ==if((semid = semget(semkey, 1, SEMPERM | IPC_CREAT| IPC_EXCL)) == --1)1)

    {{

    if(errno == EEXIST)if(errno == EEXIST)

    semid = semget(semkey, 1, 0);semid = semget(semkey, 1, 0);

    } else {} else {

    semun arg;semun arg;arg.val = 1;arg.val = 1;

    status = semctl (semid,0, SETVAL, arg);status = semctl (semid,0, SETVAL, arg);

    }}

  • 8/8/2019 Lec 20 Semaphores

    18/22

    18 CSCE 510 Fall 2005

    if(semid ==if(semid == --1 || status ==1 || status == --1)1)

    {{

    perror("initsem failed");perror("initsem failed");

    return(return(--1);1);}}

    return(semid);return(semid);

    }}

  • 8/8/2019 Lec 20 Semaphores

    19/22

    19 CSCE 510 Fall 2005

    Simple Wait wait function |set| =1Simple Wait wait function |set| =1

    int wait(int semid)int wait(int semid)

    {{

    struct sembuf p_buf;struct sembuf p_buf;

    p_buf.sen_num = 0;p_buf.sen_num = 0;p_buf.semop =p_buf.semop = --1;1; /* normal decrement by one *//* normal decrement by one */

    p_buf.sem_flg = SEM_UNDO;p_buf.sem_flg = SEM_UNDO;

    if(semop(semid, &p_buf,1) ==if(semop(semid, &p_buf,1) == --1)1)

    err_quit(wait operation failed);err_quit(wait operation failed);

    return(0);return(0);

    }}

  • 8/8/2019 Lec 20 Semaphores

    20/22

    20 CSCE 510 Fall 2005

    Simple Signal signal function |set| =1Simple Signal signal function |set| =1int signal(int semid)int signal(int semid)

    {{

    struct sembuf v_buf;struct sembuf v_buf;

    v_buf.sem_num = 0;v_buf.sem_num = 0;

    v_buf.semop = 1;v_buf.semop = 1;

    v_buf.sem_flg = SEM_UNDO;v_buf.sem_flg = SEM_UNDO;

    if(semop(semid, &v_buf, 1) ==if(semop(semid, &v_buf, 1) == --1)1)

    err_quit(wait operation failed);err_quit(wait operation failed);return(0);return(0);

    }}

  • 8/8/2019 Lec 20 Semaphores

    21/22

    21 CSCE 510 Fall 2005

    testsemtestsem

    Void handlesem(key_t skey);Void handlesem(key_t skey);

    Main(){Main(){

    int i;int i;

    key_t semkey = 0x200;key_t semkey = 0x200;for(i=0; I < 3; ++i){for(i=0; I < 3; ++i){

    if(fork() == 0)if(fork() == 0)

    handlesem(semkey);handlesem(semkey);

    }}

    }}

  • 8/8/2019 Lec 20 Semaphores

    22/22

    22 CSCE 510 Fall 2005

    void handlesem(key_t skey){void handlesem(key_t skey){

    int semid;int semid;

    pid_t pid = getpid();pid_t pid = getpid();

    if((semid = initsem(skey)) < 0) exit(1);if((semid = initsem(skey)) < 0) exit(1);

    printf(printf(\\npid %d before entering critical sectionnpid %d before entering critical section\\n, pid);n, pid);

    wait(semid);wait(semid);

    printf(printf(\\npid %d in critical sectionnpid %d in critical section\\n, pid);n, pid);

    sleep(10);sleep(10);

    printf(printf(\\npid %d leaving critical sectionnpid %d leaving critical section\\n, pid);n, pid);

    signal(semid);signal(semid);

    }}