| 首先让我们复习一下信号量是如何作为一个同步机制工作的。一般的信号量也被叫做一个计数信号量,因为带有一个可以增加的值(通常初始化为  0)。考虑一家租用自行车的商店,在它的库存中有 100 辆自行车,还有一个供职员用于租赁的程序。每当一辆自行车被租出去,信号量就增加  1;当一辆自行车被还回来,信号量就减 1。在信号量的值为 100 之前都还可以进行租赁业务,但如果等于 100  时,就必须停止业务,直到至少有一辆自行车被还回来,从而信号量减为 99。 二元信号量是一个特例,它只有两个值:0 和 1。在这种情况下,信号量的表现为互斥量(一个互斥的构造)。下面的共享内存示例将把信号量用作互斥量。当信号量的值为 0 时,只有 memwriter可以获取共享内存,在写操作完成后,这个进程将增加信号量的值,从而允许memreader来读取共享内存。 示例 3. memwriter 进程的源程序/** Compilation: gcc -o memwriter memwriter.c -lrt -lpthread **/#include <stdio.h>#include <stdlib.h>#include <sys/mman.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <semaphore.h>#include <string.h>#include "shmem.h" void report_and_exit(const char* msg) {  [perror][4](msg);  [exit][5](-1);} int main() {  int fd = shm_open(BackingFile,      /* name from smem.h */            O_RDWR | O_CREAT, /* read/write, create if needed */            AccessPerms);     /* access permissions (0644) */  if (fd < 0) report_and_exit("Can't open shared mem segment...");   ftruncate(fd, ByteSize); /* get the bytes */   caddr_t memptr = mmap(NULL,       /* let system pick where to put segment */            ByteSize,   /* how many bytes */            PROT_READ | PROT_WRITE, /* access protections */            MAP_SHARED, /* mapping visible to other processes */            fd,         /* file descriptor */            0);         /* offset: start at 1st byte */  if ((caddr_t) -1  == memptr) report_and_exit("Can't get segment...");   [fprintf][7](stderr, "shared mem address: %p [0..%d]n", memptr, ByteSize - 1);  [fprintf][7](stderr, "backing file:       /dev/shm%sn", BackingFile );   /* semahore code to lock the shared mem */  sem_t* semptr = sem_open(SemaphoreName, /* name */               O_CREAT,       /* create the semaphore */               AccessPerms,   /* protection perms */               0);            /* initial value */  if (semptr == (void*) -1) report_and_exit("sem_open");   [strcpy][8](memptr, MemContents); /* copy some ASCII bytes to the segment */   /* increment the semaphore so that memreader can read */  if (sem_post(semptr) < 0) report_and_exit("sem_post");   sleep(12); /* give reader a chance */   /* clean up */  munmap(memptr, ByteSize); /* unmap the storage */  close(fd);  sem_close(semptr);  shm_unlink(BackingFile); /* unlink from the backing file */  return 0;}
 下面是 memwriter和memreader程序如何通过共享内存来通信的一个总结: |