编码环境如下
系统环境: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 1024
union 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 create
sem_id = semget(sem_key,1,IPC_CREAT |0666);
if(-1 == sem_id)
{
printf("semget error\n");
return -1;
}
//sem init
union semun arg;
arg.val = 1;
if(semctl(sem_id,0,SETVAL,arg) == -1)
{
printf("semctl error\n");
return -1;
}
//create shm
shm_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 = -1
op.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 = 1
op.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 1024
union 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 create
sem_id = semget(sem_key,1,IPC_CREAT |0666);
if(-1 == sem_id)
{
printf("semget error\n");
return -1;
}
//sem init
union semun arg;
arg.val = 1;
if(semctl(sem_id,0,SETVAL,arg) == -1)
{
printf("semctl error\n");
return -1;
}
//create shm
shm_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 = -1
op.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 = 1
op.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博客