编码环境如下
系统环境:linux
信号量:使用Linux操作系统的SystemV信号量
生产者代码如下
#include <iostream>
#include <sys/sem.h>
#include <sys/shm.h>
#include <string.h>#define SEM_KEY 0x5678
#define SHM_KEY 0xABCD
#define SHM_SIZE 1024union semun{int val;struct semid_ds* buf;unsigned short *array;
};int main()
{key_t sem_key = SEM_KEY;key_t shm_key = SHM_KEY;char* shm_ptr = NULL;int sem_id = 0;int shm_id = 0;//sem createsem_id = semget(sem_key,1,IPC_CREAT |0666);if(-1 == sem_id){printf("semget error\n");return -1;}//sem initunion semun arg;arg.val = 1;if(semctl(sem_id,0,SETVAL,arg) == -1){printf("semctl error\n");return -1;}//create shmshm_id = shmget(shm_key,SHM_SIZE,IPC_CREAT|0666);if(-1 == shm_id){printf("shmget error\n");return -1;}static int cnt = 0;std::string data;while (true) {static struct sembuf op;//P操作op.sem_num = 0; //信号在信号集中索引,0代表第一个信号op.sem_op = -1; // P操作:sem_op = -1op.sem_flg = SEM_UNDO;if(semop(sem_id,&op,1) == -1){printf("semop wait error\n");return -1;}if(cnt > 10000000){cnt = 1;}data = "Data context: " + std::to_string(cnt++);// 将当前进程与共享内存shmid建立链接,获取共享内存地址shm_ptr = (char*)shmat(shm_id,nullptr,0);if(shm_ptr == (char*)-1){ //获取共享内存映射地址失败printf("shmat error\n");return -1;}memcpy(shm_ptr,data.c_str(),data.size() + 1);printf("Producer product Data: %s\n",shm_ptr);shmdt(shm_ptr);//V操作op.sem_num = 0; //信号在信号集中索引,0代表第一个信号op.sem_op = 1; // V操作:sem_op = 1op.sem_flg = SEM_UNDO;if(semop(sem_id,&op,1) == -1){printf("semop post error\n");return -1;}}return 0;
}
消费者代码如下:
#include <iostream>
#include <sys/sem.h>
#include <sys/shm.h>#define SEM_KEY 0x5678
#define SHM_KEY 0xABCD
#define SHM_SIZE 1024union semun{int val;struct semid_ds* buf;unsigned short *array;
};int main()
{key_t sem_key = SEM_KEY;key_t shm_key = SHM_KEY;char* shm_ptr = NULL;int sem_id = 0;int shm_id = 0;//sem createsem_id = semget(sem_key,1,IPC_CREAT |0666);if(-1 == sem_id){printf("semget error\n");return -1;}//sem initunion semun arg;arg.val = 1;if(semctl(sem_id,0,SETVAL,arg) == -1){printf("semctl error\n");return -1;}//create shmshm_id = shmget(shm_key,SHM_SIZE,IPC_CREAT|0666);if(-1 == shm_id){printf("shmget error\n");return -1;}while (true) {static struct sembuf op;op.sem_num = 0; //信号在信号集中索引,0代表第一个信号op.sem_op = -1; // P操作:sem_op = -1op.sem_flg = SEM_UNDO;if(semop(sem_id,&op,1) == -1){printf("semop wait error\n");return -1;}shm_ptr = (char*)shmat(shm_id,nullptr,0);if(shm_ptr == (char*)-1){ //获取共享内存映射地址失败printf("shmat error\n");return -1;}printf("Customer Get Data: %s\n",shm_ptr);shmdt(shm_ptr);//op.sem_num = 0; //信号在信号集中索引,0代表第一个信号op.sem_op = 1; // V操作:sem_op = 1op.sem_flg = SEM_UNDO;if(semop(sem_id,&op,1) == -1){printf("semop post error\n");return -1;}}return 0;
}
运行结果如下:
附加链接如下:
进程间通信方式介绍_夜雨听萧瑟的博客-CSDN博客
C++ 创建共享内存_c共享内存_夜雨听萧瑟的博客-CSDN博客
信号量SytemV与Posix信号量的介绍与用法_夜雨听萧瑟的博客-CSDN博客
C++信号量与共享内存实现进程间通信-CSDN博客