手撕生产者消费者问题——进程同步、进程互斥、进程通信
生产者进程
#include
#include
#include
#include
#include
#include
#include
using namespace std;
union Semun
{
short val;
struct semid_ds *buf;
unsigned short *array;
};
void EXIT(int sig = 0)
{
int shmid = shmget(0x5000, 4, 0640);
if (shmid != -1)
{
shmctl(shmid, IPC_RMID, nullptr);
}
int mutexid = semget(0x5001, 1, 0640);
if (mutexid != -1)
{
semctl(mutexid, 0, IPC_RMID, nullptr);
}
int pcSemid = semget(0x5002, 1, 0640);
if (pcSemid != -1)
{
semctl(pcSemid, 0, IPC_RMID, nullptr);
}
int cpSemid = semget(0x5003, 1, 0640);
if (cpSemid != -1)
{
semctl(cpSemid, 0, IPC_RMID, nullptr);
}
exit(0);
}
int main()
{
signal(SIGINT, EXIT);
signal(SIGTERM, EXIT);
int shmid = shmget(0x5000, 4, 0640 | IPC_CREAT);
if (shmid == -1)
{
cout << "共享内存创建失败!" << endl;
EXIT();
}
void *pshm = shmat(shmid, nullptr, 0);
int mutextid = semget(0x5001, 1, 0640 | IPC_CREAT);
if (mutextid == -1)
{
cout << "互斥信号量创建失败!" << endl;
EXIT();
}
Semun mutextValue;
mutextValue.val = 1;
if (semctl(mutextid, 0, SETVAL, mutextValue) == -1)
{
cout << "互斥信号量初始化失败!" << endl;
EXIT();
}
sembuf mutextP;
mutextP.sem_num = 0;
mutextP.sem_op = -1;
mutextP.sem_flg = 0;
sembuf mutextV;
mutextV.sem_num = 0;
mutextV.sem_op = 1;
mutextV.sem_flg = 0;
int pcSemid = semget(0x5002, 1, 0640 | IPC_CREAT);
if (pcSemid == -1)
{
cout << "生产->消费 同步信号量创建失败!" << endl;
EXIT();
}
Semun pcSemValue;
pcSemValue.val = 0;
if (semctl(pcSemid, 0, SETVAL, pcSemValue) == -1)
{
cout << "生产->消费 同步信号量初始化失败!" << endl;
EXIT();
}
sembuf pcSemOps;
pcSemOps.sem_num = 0;
pcSemOps.sem_op = 1;
pcSemOps.sem_flg = 0;
int cpSemid = semget(0x5003, 1, 0640 | IPC_CREAT);
if (cpSemid == -1)
{
cout << "消费->生产 同步信号量创建失败!" << endl;
EXIT();
}
Semun cpSemValue;
cpSemValue.val = 1;
if (semctl(cpSemid, 0, SETVAL, cpSemValue) == -1)
{
cout << "消费->生产 同步信号量初始化失败!" << endl;
EXIT();
}
sembuf cpSemOps;
cpSemOps.sem_num = 0;
cpSemOps.sem_op = -1;
cpSemOps.sem_flg = 0;
srand((unsigned int)time(nullptr));
while (true)
{
sleep(3);
int value = rand();
if (semop(cpSemid, &cpSemOps, 1) == -1)
{
cout << "消费->生产 同步信号量的p操作失败!" << endl;
EXIT();
}
if (semop(mutextid, &mutextP, 1) == -1)
{
cout << "互斥信号量p操作失败!" << endl;
EXIT();
}
cout << "向共享内存中写入数据:" << value << endl;
memmove(pshm, &value, 4);
if (semop(mutextid, &mutextV, 1) == -1)
{
cout << "互斥信号量v操作失败!" << endl;
EXIT();
}
if (semop(pcSemid, &pcSemOps, 1) == -1)
{
cout << "生产->消费 同步信号量的v操作失败!" << endl;
EXIT();
}
}
return 0;
}
消费者进程
#include
#include
#include
#include
#include
using namespace std;
int main()
{
int shmid = shmget(0x5000, 4, 0640);
if (shmid == -1)
{
cout << "无法获取共享内存!" << endl;
exit(-1);
}
void *pshm = shmat(shmid, nullptr, 0);
int mutexid = semget(0x5001, 1, 0640);
if (mutexid == -1)
{
cout << "互斥信号量获取失败!" << endl;
exit(-1);
}
sembuf mutexP;
mutexP.sem_num = 0;
mutexP.sem_op = -1;
mutexP.sem_flg = 0;
sembuf mutexV;
mutexV.sem_num = 0;
mutexV.sem_op = 1;
mutexV.sem_flg = 0;
int pcSemid = semget(0x5002, 1, 0640);
if (pcSemid == -1)
{
cout << "获取 生产者->消费者同步信号量失败!" << endl;
exit(-1);
}
sembuf pcSemOps;
pcSemOps.sem_num = 0;
pcSemOps.sem_op = -1;
pcSemOps.sem_flg = 0;
int cpSemid = semget(0x5003, 1, 0640);
if (cpSemid == -1)
{
cout << "获取 消费者->生产者同步信号量失败!" << endl;
exit(-1);
}
sembuf cpSemOps;
cpSemOps.sem_num = 0;
cpSemOps.sem_op = 1;
cpSemOps.sem_flg = 0;
while (true)
{
int value = 100;
if (semop(pcSemid, &pcSemOps, 1) == -1)
{
cout << "生产->消费 同步信号量的p操作失败!" << endl;
exit(-1);
}
if (semop(mutexid, &mutexP, 1) == -1)
{
cout << "互斥信号量p操作失败!" << endl;
exit(-1);
}
memmove(&value, pshm, 4);
cout << "从共享内存中读取到的数据是:" << value << endl;
if (semop(mutexid, &mutexV, 1) == -1)
{
cout << "互斥信号量v操作失败!" << endl;
exit(-1);
}
if (semop(cpSemid, &cpSemOps, 1) == -1)
{
cout << "消费->生产 同步信号量的v操作失败!" << endl;
exit(-1);
}
}
return 0;
}
结果