c - 如何在 C 中的生产者/消费者问题中使用信号量作为共享变量(共享内存)
问题描述
我一直在尝试在生产者/消费者问题中使用信号量,但我不知道如何在共享内存中声明信号量和互斥锁并在两个进程中使用它们。我当前的程序无法正常工作,但我将它们附在此处。请给我建议,并在此先感谢您。
生产者.c
#include "protocol.h"
// producer Code
static const char name[] = "sem";
void producer(struct ShmData *shmData, sem_t *sem) {
for(int i = 0 ; i < 8; i++) {
sleep(1);
sem_post(sem);
// If mutex is 1 and buffer is not full, then it is
// possible to produce
if ((shmData->mutex == 1) && (shmData->empty != 0)) {
// Producer code starts here
// Decrease mutex value by 1
shmData->mutex = (shmData->mutex)-1; // mutex--
// Decrease the number of buffer by 1
shmData->full = (shmData->full) + 1; //full++
shmData->empty = (shmData->empty) - 1; //empty--
// Item produced
shmData->x = (shmData->x) + 1; //x++
printf("\nProducer produces item %d", shmData->x);
// Increase mutex value by 1
shmData->mutex = (shmData->mutex) + 1; //mutex++
// Producer code ends here
}
}
}
int main()
{
sem_unlink(name);
sem_t *sem = sem_open(name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
int fd = shm_open(NAME, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd < 0) {
perror("shm_open() producer error");
close(fd);
shm_unlink(NAME);
return EXIT_FAILURE;
}
ftruncate(fd, SIZE);
struct ShmData *shmData = mmap(0, sizeof(*shmData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
shmData->mutex = 1; // mutual exclusion
shmData->full = 0;
shmData->empty = BUFFER;
shmData->x = 0; // Item number
pthread_t th[THREAD_NUM];
for (int i = 0; i < THREAD_NUM; i++) {
if (pthread_create(&th[i], NULL, &producer, shmData) != 0) {
perror("Failed to create thread");
}
}
for (int i = 0; i < THREAD_NUM; i++) {
if (pthread_join(th[i], NULL) != 0) {
perror("Failed to join thread");
}
}
munmap(shmData, SIZE);
close(fd);
return EXIT_SUCCESS;
}
消费者.c
/* https://www.geeksforgeeks.org/producer-consumer-problem-in-c/ */
#include "protocol.h"
// consumer Code
void consumer(struct ShmData *shmData) {
for(int i = 0 ; i < 8; i++) {
sleep(2);
// If mutex is 1 and buffer is not empty, then it is
// possible to consume
if ((shmData->mutex == 1) && (shmData->full != 0)) {
// consumer code starts here
// Decrease mutex value by 1
shmData->mutex = (shmData->mutex) - 1; // mutex--
// Increase the number of empty
// slots by 1
shmData->full = (shmData->full) - 1; // full--;
shmData->empty = (shmData->empty) + 1; // empty++;
printf("\nConsumer consumes item %d", shmData->x);
shmData->x = (shmData->x) - 1; // x--;
// Increase mutex value by 1
shmData->mutex = (shmData->mutex) + 1; // mutex++;
// consumer code ends here
}
sleep(1);
}
}
int main()
{
sleep(1);
int fd = shm_open(NAME, O_EXCL | O_RDWR, 0600);
if (fd < 0) {
perror("shm_open() consumer error");
close(fd);
shm_unlink(NAME);
return EXIT_FAILURE;
}
ftruncate(fd, SIZE);
struct ShmData *shmData = mmap(0, sizeof(*shmData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
pthread_t th[THREAD_NUM];
for (int i = 0; i < THREAD_NUM; i++) {
if (pthread_create(&th[i], NULL, &consumer, shmData) != 0) {
perror("Failed to create thread");
}
}
for (int i = 0; i < THREAD_NUM; i++) {
if (pthread_join(th[i], NULL) != 0) {
perror("Failed to join thread");
}
}
munmap(shmData, SIZE);
close(fd);
shm_unlink(NAME);
return EXIT_SUCCESS;
}
协议.h
#ifndef PROTOCOL_H
#define PROTOCOL_H
#define NAME "/pcp-sharemem"
#define NUM 4
#define SIZE (NUM * sizeof(int))
#define BUFFER 2
#define THREAD_NUM 1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <pthread.h>
#include <err.h>
#include <semaphore.h>
struct ShmData {
int mutex;
int full;
int empty;
int x;
};
#endif /* PROTOCOL_H */
解决方案
推荐阅读
- python - 为 Python 2.7 安装 opencv 时出现 DLL Load failed 错误
- html - 使用 FlexBox(或其他 css),是否可以在每行中拥有不同数量的相同大小的列(即不使用空 div)?
- javascript - 添加新项目 React 时状态数组未正确更新?
- python - 区分类属性
- javascript - 使用 JavaScript 在点击时进一步移动元素?
- sql - 使用 VB.Net 访问数据库存储过程后返回 True/False
- apache - 使用 mod_security 的跨站 URL 链接
- mysql - 设计 XtraDB 集群
- tfs - 我的一个 VSTS 帐户中名为 SCRUMUA 的继承过程模板没有导出到我的另一个 VSTS 帐户
- java - 在 sftp 中使用“put”命令给出没有这样的文件或目录 3:权限被拒绝