设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 手机 数据 公司
当前位置: 首页 > 服务器 > 搭建环境 > Windows > 正文

Linux下的进程间通信:共享存储(4)

发布时间:2019-05-08 16:31 所属栏目:117 来源:Marty Kalin
导读:首先让我们复习一下信号量是如何作为一个同步机制工作的。一般的信号量也被叫做一个 计数信号量 ,因为带有一个可以增加的值(通常初始化为 0)。考虑一家租用自行车的商店,在它的库存中有 100 辆自行车,还有一个

首先让我们复习一下信号量是如何作为一个同步机制工作的。一般的信号量也被叫做一个计数信号量,因为带有一个可以增加的值(通常初始化为 0)。考虑一家租用自行车的商店,在它的库存中有 100 辆自行车,还有一个供职员用于租赁的程序。每当一辆自行车被租出去,信号量就增加 1;当一辆自行车被还回来,信号量就减 1。在信号量的值为 100 之前都还可以进行租赁业务,但如果等于 100 时,就必须停止业务,直到至少有一辆自行车被还回来,从而信号量减为 99。

二元信号量是一个特例,它只有两个值:0 和 1。在这种情况下,信号量的表现为互斥量(一个互斥的构造)。下面的共享内存示例将把信号量用作互斥量。当信号量的值为 0 时,只有 memwriter 可以获取共享内存,在写操作完成后,这个进程将增加信号量的值,从而允许 memreader 来读取共享内存。

示例 3. memwriter 进程的源程序

  1. /** Compilation: gcc -o memwriter memwriter.c -lrt -lpthread **/
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/mman.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <semaphore.h>
  9. #include <string.h>
  10. #include "shmem.h"
  11.  
  12. void report_and_exit(const char* msg) {
  13. [perror][4](msg);
  14. [exit][5](-1);
  15. }
  16.  
  17. int main() {
  18. int fd = shm_open(BackingFile, /* name from smem.h */
  19. O_RDWR | O_CREAT, /* read/write, create if needed */
  20. AccessPerms); /* access permissions (0644) */
  21. if (fd < 0) report_and_exit("Can't open shared mem segment...");
  22.  
  23. ftruncate(fd, ByteSize); /* get the bytes */
  24.  
  25. caddr_t memptr = mmap(NULL, /* let system pick where to put segment */
  26. ByteSize, /* how many bytes */
  27. PROT_READ | PROT_WRITE, /* access protections */
  28. MAP_SHARED, /* mapping visible to other processes */
  29. fd, /* file descriptor */
  30. 0); /* offset: start at 1st byte */
  31. if ((caddr_t) -1 == memptr) report_and_exit("Can't get segment...");
  32.  
  33. [fprintf][7](stderr, "shared mem address: %p [0..%d]\n", memptr, ByteSize - 1);
  34. [fprintf][7](stderr, "backing file: /dev/shm%s\n", BackingFile );
  35.  
  36. /* semahore code to lock the shared mem */
  37. sem_t* semptr = sem_open(SemaphoreName, /* name */
  38. O_CREAT, /* create the semaphore */
  39. AccessPerms, /* protection perms */
  40. 0); /* initial value */
  41. if (semptr == (void*) -1) report_and_exit("sem_open");
  42.  
  43. [strcpy][8](memptr, MemContents); /* copy some ASCII bytes to the segment */
  44.  
  45. /* increment the semaphore so that memreader can read */
  46. if (sem_post(semptr) < 0) report_and_exit("sem_post");
  47.  
  48. sleep(12); /* give reader a chance */
  49.  
  50. /* clean up */
  51. munmap(memptr, ByteSize); /* unmap the storage */
  52. close(fd);
  53. sem_close(semptr);
  54. shm_unlink(BackingFile); /* unlink from the backing file */
  55. return 0;
  56. }

下面是 memwritermemreader 程序如何通过共享内存来通信的一个总结:

  • 上面展示的 memwriter 程序调用 shm_open 函数来得到作为系统协调共享内存的备份文件的文件描述符。此时,并没有内存被分配。接下来调用的是令人误解的名为 ftruncate 的函数

    1. ftruncate(fd, ByteSize); /* get the bytes */

    (编辑:ASP站长网)

网友评论
推荐文章
    热点阅读