一个简单的共享内存、信号灯代码案例

  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/ipc.h>
  4 #include <sys/shm.h>
  5 #include <errno.h>
  6 #include <sys/sem.h>
  7 #include <string.h>
  8 
  9 #define N 128
 10 struct shmbuf{
 11     char buf[N];
 12 };
 13 union semun{
 14     int val;
 15 };
 16 int main(int argc, const char *argv[])
 17 {
 18     key_t key;
 19 
 20     if((key = ftok(".", 'q')) < 0){
 21         perror("ftok error");
 22         return -1;
 23     }
 24 
 25     int shmid;
 26     struct shmbuf *shm;
 27     if((shmid = shmget(key, 512, IPC_CREAT|IPC_EXCL|0664)) < 0){
 28         if(errno != EEXIST){
 29             perror("shmget error");
 30             return -1;
 31         }
 32         else{
 33             shmid = shmget(key, 512, 0664);
 34         }
 35     }
 36 
 37     if((shm = shmat(shmid, NULL, 0)) > 0){
 38         printf("shm:%p\n", shm);
 39     }
 40 
 41     int semid;
 42     union semun semun;
 43 
 44     struct sembuf sem;
 45     semid = semget(key, 2, IPC_CREAT|IPC_EXCL|0664);
 46 
 47     if(semid < 0){
 48         if(errno != EEXIST){
 49             perror("semget error");
 50             return -1;
 51         }
 52         else{
 53             semid = semget(key, 2, 0664);
 54         }
 55     }
 56     else{
 57         /*初始化信号量的值*/
 58         semun.val = 0;
 59         semctl(semid, 0, SETVAL, semun);
 60         semun.val = 1;
 61         semctl(semid, 1, SETVAL, semun);
 62     }
 63 
 64     while(1){
 65         /*申请写操作信号量*/                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
 66         sem.sem_num = 1;
 67         sem.sem_op = -1;
 68         sem.sem_flg = 0;
 69         semop(semid, &sem, 1);
 70 
 71         fgets(shm->buf, N, stdin);
 72         shm->buf[strlen(shm->buf) - 1] = '\0';
 73 
 74 
 75         /*释放读操作信号量*/
 76         sem.sem_num = 0;
 77         sem.sem_op = 1;
 78         sem.sem_flg = 0;
 79         semop(semid, &sem, 1);
 80 
 81         if(strncmp(shm->buf, "quit", 4) == 0){
 82             goto ERR;
 83         }
 84     }
 85     return 0;
 86 ERR:
 87     shmdt(shm);
 88 }
  读共享内存的代码如下,程序不退出,可以持续读取。
  1 #include <stdio.h>
  2 #include <sys/types.h>
  3 #include <sys/ipc.h>
  4 #include <sys/shm.h>
  5 #include <errno.h>
  6 #include <sys/sem.h>
  7 #include <string.h>
  8 
  9 #define N 128
 10 struct shmbuf{
 11     char buf[N];
 12 };
 13 union semun{
 14     int val;
 15 };
 16 int main(int argc, const char *argv[])
 17 {
 18     key_t key;
 19 
 20     if((key = ftok(".", 'q')) < 0){
 21         perror("ftok error");
 22         return -1;
 23     }
 24 
 25     int shmid;
 26     struct shmbuf *shm;
 27     /*创建并打开共享内存*/
 28     if((shmid = shmget(key, 512, IPC_CREAT|IPC_EXCL|0664)) < 0){
 29         if(errno != EEXIST){
 30             perror("shmget error");
 31             return -1;
 32         }
 33         else{
 34             /*如果共享内存已存在,则打开*/
 35             shmid = shmget(key, 512, 0664);
 36         }
 37     }
 38 
 39     /*建立映射*/
 40     if((shm = shmat(shmid, NULL, 0)) > 0){
 41         printf("shm:%p\n", shm);
 42     }
 43 
 44     int semid;
 45     union semun semun;                                                                                                                                                                                                                                                                                                                                                                                                                     
 46 
 47     struct sembuf sem;
 48     /*创建并打开信号量集合*/
 49     semid = semget(key, 2, IPC_CREAT|IPC_EXCL|0664);
 50 
 51     if(semid < 0){
 52         if(errno != EEXIST){
 53             perror("semget error");
 54             return -1;
 55         }
 56         else{
 57             /*如果信号量集存在,则打开*/
 58             semid = semget(key, 2, 0664);
 59         }
 60     }
 61     else{
 62         /*初始化信号量的值
 63          *将编号为0的信号量定义为读操作信号量
 64          *读操作信号量初始化值为0
 65          */
 66         semun.val = 0;
 67         semctl(semid, 0, SETVAL, semun);
 68         /*将编号为1的信号量定义为写操作信号量
 69          *写操作信号量初始值为1
 70          */
 71         semun.val = 1;
 72         semctl(semid, 1, SETVAL, semun);
 73     }
 74 
 75     while(1){
 76         //申请读操作信号量
 77         sem.sem_num = 0;
 78         sem.sem_op = -1;
 79         sem.sem_flg = 0;
 80         semop(semid, &sem, 1);
 81 
 82         if(strncmp(shm->buf, "quit", 4) == 0){
 83             goto ERR;
 84         }
 85         printf("buf:%s\n", shm->buf);
 86                                                                                                                                                                                      
 87         //释放写操作信号量
 88         sem.sem_num = 1;
 89         sem.sem_op = 1;
 90         sem.sem_flg = 0;
 91         semop(semid, &sem, 1);
 92     }
 93     return 0;
 94 ERR:
 95     shmdt(shm);
 96     shmctl(shmid, IPC_RMID, NULL);
 97     semctl(semid, 0, IPC_RMID, NULL);
 98     semctl(semid, 1, IPC_RMID, NULL);
 99 } 
运行结果如下,从终端输入,另外一个进程则读取数据并输出,当输入“quit”时,程序全部退出,且删除一切资源。
linux@Master:~/1000phone/sem$ ./write 
shm:0x7ffcee3df000
hello
world
quit  
执行读操作程序。
linux@Master:~/1000phone/sem$ ./read 
shm:0x7f20ccdb4000
buf:hello
buf:world   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值