CSCE 313 Lecture 17
Jump to navigation
Jump to search
« previous | Thursday, March 22, 2012 | next »
Review: Interprocess Communication
Message Queue
struct mymsg { /* user-defined */
long msgtype; /* first field must be a long identifier */
char mtext[1]; /* placeholder for message content */
}
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
int msgctl(int msqid, int cmd, struct msgid_ds *buf);
Program 15.9 msgqueuelog.c (Chapter 15)
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflag); // allocate shared memory
void *shmat(int shmid, const void *shmaddr, int shmflg); // get data from shared memory
(Binary) Semaphores
#include <sys/sem.h>
int semget(key_t, int nsems, int semflg); // create semaphore set with nsems semaphores; 0 if set already exists
int semctl(int semid, int semnum, int cmd, ...);</code c>
unlike the semaphores previously mentioned, which have P and V operations, POSIX semaphores have only one operation:
<syntaxhighlight lang="c">#include <sys/sem.h>
int semop(int semid, struct sembuf *sopos, size_t, nsops);
struct sembuf {
short sem_num; // number of semaphore elements
short sem_op; // operation to be performed
short sem_flg; // options for the operation
}
sem_op > 0 | Similar to V operation: add value to semaphore element and awaken all processes that are waiting for element to increase |
sem_op == 0 && semval != 0 | Similar to P operation: block calling process (waiting for 0) and increment the count of processes waiting for 0 |
sem_op < 0 | add sem_op value to semaphore element value provided that result would not be negative. If result is negative, block process and wait for 0 |
struct sembuf get_tapes[2];
struct sembuf release_tapes[2];
// num op flag
setsembuf(&(get_tapes[0]), 0, -1, 0); // P operation for first tape drive
setsembuf(&(get_tapes[1]), 1, -1, 0); // P operation for second tape drive
setsembuf(&(release_tapes[0]), 0, +1, 0); // V operation for first tape drive
setsembuf(&(release_tapes[1]), 1, +1, 0); // V operation for second tape drive
semop(S, get_tapes, 1);
// use Tape 0
semop(S, release_tapes, 1);
semop(S, get_tapes, 2);
// use both tapes 0 and 1
semop(S, release_tapes, 2);
Control access to critical section
int main(int argc, char *argv[]) {
int semid;
struct sembuf sem_signal[1];
struct sembuf sem_wait[1];
semid = semget(IPC_PRIVATE, 1, PERMS);
setsembuf(sem_wait, 0, -1, 0);
setsembuf(sem_signal, 0, 1, 0);
init_element(semid, 0, 1);
// create chain of n processes
for (int i=1; i<n; i++) if fork() break;
semop(semid, sem_wait, 1); // enter critical section
// in critical section
semop(semid, sem_signal, 1); // exit critical section
return 0;
}