Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55239
  • 博文数量: 21
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-23 15:40
文章分类

全部博文(21)

文章存档

2013年(21)

我的朋友

分类: LINUX

2013-05-09 19:04:55

两个进程 通过共享内存 信号灯 通信(一)
 实现最简单的功能 :一个读 一个写 


write.c

点击(此处)折叠或打开

  1. //-------------------------------------
  2. //两个进程通信 共享内存方式
  3. //利用 信号灯 控制进程间的同步 和互斥
  4. //2013-4-13
  5. //-------------------------------------

  6. #include <stdio.h>
  7. #include <sys/ipc.h>
  8. #include <sys/shm.h>
  9. #include <sys/types.h>
  10. #include <sys/sem.h>
  11. #include <errno.h>

  12. #define N 64 // sizeof buf

  13. union semun {
  14.                int val; /* Value for SETVAL */
  15.                struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
  16.                unsigned short *array; /* Array for GETALL, SETALL */
  17.                struct seminfo *__buf; /* Buffer for IPC_INFO
  18.                                            (Linux-specific) */
  19. };


  20. // struct of share memory
  21. typedef struct share_memory
  22. {
  23.     char buf [N];
  24. }sMemory;


  25. //-----creat or open the memory----- return the shmid

  26. int crop_memory(key_t key)
  27. {
  28.     int shmid;

  29.     if(-1 == (shmid = shmget(key, sizeof(sMemory), IPC_CREAT | IPC_EXCL | 0666)))
  30.     {
  31.         if(errno == EEXIST)
  32.         {
  33.             shmid = shmget(key, sizeof(sMemory), 0666);
  34.             //printf("the share memory has been created!\n");
  35.             return shmid; // open success ,return the shmid
  36.         }
  37.         else
  38.         {
  39.             perror("shmget");
  40.             return -1;
  41.         }
  42.     }
  43.     // else creat success

  44.     return shmid;
  45. }

  46. //------------- attached -----------

  47. sMemory *
  48. attached(int shmid)
  49. {
  50.     sMemory * add;
  51.     if(NULL == (add = (sMemory *)shmat(shmid, NULL, 0)))        //NULL : the system chooses a suitable (unused)
  52.     {                                        //address at which to attach the segment
  53.         perror("shmat");
  54.         return NULL;
  55.     }                                            

  56.     return add;
  57. }

  58. //------- creat or open semaphore -------
  59. int crop_semaphore(key_t key)
  60. {
  61.     int semid;

  62.     if(-1 == (semid = semget(key, 2, 0666 | IPC_CREAT | IPC_EXCL )))
  63.     {
  64.         if(errno == EEXIST)
  65.         {
  66.             semid = semget(key, 2, 0666);
  67.             //printf("the semaphore has been created !\n");
  68.         }
  69.         else{
  70.             perror("semget");
  71.             return -1;
  72.         }
  73.     }
  74.     else{ // created semaphore success , inited
  75.         union semun u; // 0 - read ; 1 - write

  76.         u.val = 0;
  77.         if(-1 == semctl(semid, 0, SETVAL, u))        // set 0 - read : 0
  78.         {
  79.             perror("semctl 1");
  80.             return -1;
  81.         }

  82.         u.val = 1;
  83.         if(-1 == semctl(semid, 1, SETVAL, u))    //set 1-write : 1
  84.         {
  85.             perror("semctl 2");
  86.             return -1;
  87.         }
  88.     }

  89.     return semid;
  90. }

  91. //------------- set_wsops------------
  92. void set_wsops(struct sembuf * sops)
  93. {
  94.     sops->sem_num = 1;
  95.     sops->sem_op = -1;
  96.     sops->sem_flg = 0;
  97. }

  98. //------------- set_rsops------------
  99. void set_rsops(struct sembuf * sops)
  100. {
  101.     sops->sem_num = 0;
  102.     sops->sem_op = 1;
  103.     sops->sem_flg = 0;
  104. }

  105. //----------sem_opration------------
  106. int sem_opration(int semid, struct sembuf *sops, unsigned nsops)
  107. {
  108.     if(-1 == semop(semid, sops, nsops))
  109.     {
  110.         perror("semop");
  111.         return -1;
  112.     }
  113. }

  114. //------------- main ---------------

  115. int main(void)
  116. {
  117.     key_t key;
  118.     int shmid;
  119.     int semid; // the identifier of semaphore
  120.     sMemory * add; // the address of the attached shared memory
  121.     struct sembuf sops;

  122.     if(-1 == (key = ftok(".", 'l')))
  123.     {
  124.         perror("ftok");
  125.         return -1;
  126.     }

  127.     shmid = crop_memory(key); // creat or open share memory
  128.     add = attached(shmid);        // attached
  129.     semid = crop_semaphore(key); //create or oen semaphore

  130.     while(1)
  131.     {
  132.         set_wsops(&sops); // p option for semaphore 1 - write
  133.         sem_opration(semid, &sops, 1);

  134.         fgets(add->buf, sizeof(add->buf), stdin);
  135.         //printf("%s", add->buf); // 若在此处读取共享内存中的数据,
  136.                                     //读放也能再读取。说明读操作没有清空内存!!!

  137.         set_rsops(&sops); // v option for semaphore o - read
  138.         sem_opration(semid, &sops, 1);
  139.     }

  140.     return 0;
  141. }

read.c

点击(此处)折叠或打开

  1. //-------------------------------------
  2. //两个进程通信 共享内存方式
  3. //利用 信号灯 控制进程间的同步 和互斥
  4. //2013-4-13
  5. //-------------------------------------

  6. #include <stdio.h>
  7. #include <sys/ipc.h>
  8. #include <sys/shm.h>
  9. #include <sys/types.h>
  10. #include <sys/sem.h>
  11. #include <errno.h>

  12. #define N 64 // sizeof buf

  13. union semun {
  14.                int val; /* Value for SETVAL */
  15.                struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
  16.                unsigned short *array; /* Array for GETALL, SETALL */
  17.                struct seminfo *__buf; /* Buffer for IPC_INFO
  18.                                            (Linux-specific) */
  19. };


  20. // struct of share memory
  21. typedef struct share_memory
  22. {
  23.     char buf [N];
  24. }sMemory;


  25. //-----creat_memory----- return the shmid

  26. int crop_memory(key_t key)
  27. {
  28.     int shmid;

  29.     if(-1 == (shmid = shmget(key, sizeof(sMemory), IPC_CREAT | IPC_EXCL | 0666)))
  30.     {
  31.         if(errno == EEXIST)
  32.         {
  33.             shmid = shmget(key, sizeof(sMemory), 0666);
  34.             //printf("the share memory has been created!\n");
  35.             return shmid; // open success ,return the shmid
  36.         }
  37.         else
  38.         {
  39.             perror("shmget");
  40.             return -1;
  41.         }
  42.     }
  43.     // else creat success

  44.     return shmid;
  45. }

  46. //------------- attached -----------

  47. sMemory *
  48. attached(int shmid)
  49. {
  50.     sMemory * add;
  51.     if(NULL == (add = (sMemory *)shmat(shmid, NULL, 0)))        //NULL : the system chooses a suitable (unused)
  52.     {                                        //address at which to attach the segment
  53.         perror("shmat");
  54.         return NULL;
  55.     }                                            

  56.     return add;
  57. }

  58. //------- creat or open semaphore -------
  59. int crop_semaphore(key_t key)
  60. {
  61.     int semid;

  62.     if(-1 == (semid = semget(key, 2, 0666 | IPC_CREAT | IPC_EXCL )))
  63.     {
  64.         if(errno == EEXIST)
  65.         {
  66.             semid = semget(key, 2, 0666);
  67.             //printf("the semaphore has been created !\n");
  68.         }
  69.         else{
  70.             perror("semget");
  71.             return -1;
  72.         }
  73.     }
  74.     else{ // created semaphore success , inited
  75.         union semun u; // 0 - read ; 1 - write

  76.         u.val = 0;
  77.         if(-1 == semctl(semid, 0, SETVAL, u))    // set 0 - read : 0
  78.         {
  79.             perror("semctl 1");
  80.             return -1;
  81.         }

  82.         u.val = 1;
  83.         if(-1 == semctl(semid, 1, SETVAL, u))    //set 1-write : 1
  84.         {
  85.             perror("semctl 2");
  86.             return -1;
  87.         }
  88.     }

  89.     return semid;
  90. }

  91. //------------- set_wsops------------
  92. void set_wsops(struct sembuf * sops)
  93. {
  94.     sops->sem_num = 1;
  95.     sops->sem_op = 1;
  96.     sops->sem_flg = 0;
  97. }

  98. //------------- set_rsops------------
  99. void set_rsops(struct sembuf * sops)
  100. {
  101.     sops->sem_num = 0;
  102.     sops->sem_op = -1;
  103.     sops->sem_flg = 0;
  104. }

  105. //----------sem_opration------------
  106. int sem_opration(int semid, struct sembuf *sops, unsigned nsops)
  107. {
  108.     if(-1 == semop(semid, sops, nsops))
  109.     {
  110.         perror("semop");
  111.         return -1;
  112.     }
  113. }

  114. //------------- main ---------------

  115. int main(void)
  116. {
  117.     key_t key;
  118.     int shmid;
  119.     int semid; // the identifier of semaphore
  120.     sMemory * add; // the address of the attached shared memory
  121.     struct sembuf sops;

  122.     if(-1 == (key = ftok(".", 'l')))
  123.     {
  124.         perror("ftok");
  125.         return -1;
  126.     }

  127.     shmid = crop_memory(key); // creat or open share memory
  128.     add = attached(shmid);        // attached
  129.     semid = crop_semaphore(key); //create or oen semaphore

  130.     while(1)
  131.     {
  132.         set_rsops(&sops); // p option for semaphore 1 - read
  133.         sem_opration(semid, &sops, 1);

  134.         //fgets(add->buf, sizeof(add->buf), stdin);
  135.         printf("%s", add->buf);

  136.         set_wsops(&sops); // v option for semaphore o - write
  137.         sem_opration(semid, &sops, 1);
  138.     }

  139.     return 0;
  140. }

运行截图


注意:此程序没有包含共享内存的删除功能,需要人为删除。否则下次再启动程序时无法再向共享内存中写入数据。
删除共享内存方法
一: 输入命令 ipcs


二:输入 ipcrm -m shmid  (此处的shmid是 如上图中的 262144)
三:输入ipcrm -s semid (此处的semid 是 上图中的 262144)
完毕

阅读(1139) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~