c - 为什么即使缓冲区已满,生产者进程也不会停止生产?
问题描述
我用m个生产者进程和n个消费者进程编写了一个生产者-消费者同步代码。我在调试它时遇到了麻烦。缓冲区在所有消费者和生产者进程之间共享,而变量在所有生产者进程之间共享。每个产品都由一个产品 ID 表示。
有3个信号量:
i) 如果 Full semaphore 值为 0,Full semaphore 将停止消费者进程访问缓冲区。
ii) 如果 Empty semaphore 值为 0,Empty semaphore 将停止生产者进程访问缓冲区。
iii) 互斥信号量用于互斥。
共享.h
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define buffer_size 5
#define empty_id 0
#define full_id 1
#define mutex_id 2
#define no_sem 3
struct sembuf signall = {0 , 1, 0};
struct sembuf wait = {0, -1, 0};
#define W(s) semop(s, &wait, 1);
#define S(s) semop(s, &signall, 1);
int shmid,shmid1,shmid2;
int *buffer;
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
}setvalarg[3];
int *create_shared_mem_buffer()
{
int *shmaddr;
key_t key = 85;
shmid = shmget(key, buffer_size, IPC_CREAT|0660);
shmaddr= (int *)shmat(shmid, NULL, 0);
return shmaddr;
}
int create_semaphore_set()
{
key_t key=65;
int semid= semget(key, no_sem, IPC_CREAT|0600);
setvalarg[0].val=buffer_size;
semctl(semid, empty_id, SETVAL, setvalarg[0]);
setvalarg[1].val=0;
semctl(semid, full_id, SETVAL, setvalarg[1]);
setvalarg[2].val=1;
semctl(semid, mutex_id, SETVAL, setvalarg[2]);
return semid;
}
制作人.c
#include "shared.h"
void insert_product(int item, int *in, int *buffer)
{
*in=(*in+1)%buffer_size;
buffer[*in]=item;
printf("Producer produces item with id %d stored in posn %d \n",item,*in);
}
int main(int argc, char *argv[])
{
int i, pid, item;
int *in, *in1;
buffer = create_shared_mem_buffer();
int semid= create_semaphore_set();
shmid2= shmget(IPC_PRIVATE, sizeof(int),IPC_CREAT | 0777);
in=(int *)shmat(shmid2, NULL, 0);
*in=-1;
int n=5;
for(i=0;i<n;i++)
{
pid=fork();
if(pid==0)
{
srand(getpid());
in1=(int *)shmat(shmid2, NULL, 0);
while(1)
{
item=rand();
wait.sem_num=0;
W(semid);
wait.sem_num=2;
W(semid);
insert_product(item, in1, buffer);
signall.sem_num=2;
S(semid);
signall.sem_num=1;
S(semid);
}
}
}
return(0);
}
问题是生产者进程在生产 5(buffer_size) 个产品后应该等待消费者进程消费产品,然后再次填充缓冲区。
输出如下:(没有执行消费者进程)
Producer produces item with id 1170454448 stored in posn 0
Producer produces item with id 1942442557 stored in posn 1
Producer produces item with id 1638563672 stored in posn 2
Producer produces item with id 1338160125 stored in posn 3
Producer produces item with id 2111694856 stored in posn 4
Producer produces item with id 1525954635 stored in posn 0
Producer produces item with id 1346192014 stored in posn 1
Producer produces item with id 1158563802 stored in posn 2
Producer produces item with id 973413556 stored in posn 3
Producer produces item with id 787723313 stored in posn 4
什么/哪里有问题?如何调试它?
如果需要更多信息,请在下面发表评论。
解决方案
推荐阅读
- node.js - 我无法弄清楚为什么我的提示不起作用。界面提示符?
- javascript - 将css宽度作为数字而不是百分比
- css - Overflow-y with flex-end - 为什么没有滚动条?
- angular - 平板电脑数字输入键的代码是什么?
- google-sheets - Google 表格会根据特定重复项突出显示单元格
- model-view-controller - 在一个 POST 中创建父对象和子对象 - MVC Core
- javascript - 在相邻组件之间共享内容,HOC?
- html - 修复 IE 中的滚动条问题
- sonata-admin - Symfony 4 & Sonata Admin 3 警告:spl_object_hash() 期望参数 1 是对象,给定字符串
- javascript - JQuery 循环仅评估第一项