为什么,对于我的代码显示的输出的前几次迭代,消费者消耗0两次,当它应该消耗前两个产生的项目?
Consumer consumes 0
Producer produces 17
Producer produces 17
Consumer consumes 0
Producer produces 10
Producer produces 12
Consumer consumes 10
Producer produces 11
Producer produces 43
Consumer consumes 12
Producer produces 33
Producer produces 39
Consumer consumes 11
这是我的一些显示代码
#define N 10
typedef int semaphore;
semaphore mutex, full, empty;
int first=0,last=0, semArray[N];
可以使用全局变量吗?
int produce_item(){
int item = rand()%50 +1;
printf("Producer produces %d\n",item);
sleep(1);
return item;
}
void consume_item(int item){
printf("Consumer consumes %d\n",item);
sleep(2);
}
int remove_item(){
int temp = semArray[first];
first = first +1;
return temp;
}
void insert_item(int item){
semArray[last] = item;
last++;
}
这是信号量的生产者和消费者功能
void* consumer(void* arg) {
int item, i=0;
while(1){
down(full);
down(mutex);
item = remove_item();
up(mutex);
up(empty);
consume_item(item);
}
return 0;
}
void* producer(void* arg) {
int item, i=0;
while(1){
item=produce_item();
down(empty);
down(mutex);
insert_item(item);
up(mutex);
up(full);
}
return 0;
}
void down(semaphore s){
setSemaphore(s,0,-1);
}
void up(semaphore s){
setSemaphore(s,0,1);
}
int setSemaphore(int semID, int semNum, int semOp){
struct sembuf Buf;
Buf.sem_num = semNum;
Buf.sem_op = semOp;
Buf.sem_flg = 0;
return semop(semID,&Buf,1);
}
main() {
int i;
pthread_t threads[2];
srand(time(NULL));
int semid_full, semid_empty, semid_mutex;
key_t key;
key = ftok("task2.c", 'J');
//initialize and create each semaphore set
semid_empty = semget(key, 1, 0600|IPC_CREAT);
arg.val = N;
semctl(semid_empty, 0, SETVAL, arg);
semid_full = semget(key, 1, 0600|IPC_CREAT);
arg.val = 0;
semctl(semid_empty, 0, SETVAL, arg);
semid_mutex = semget(key, 1, 0600|IPC_CREAT);
arg.val = 1;
semctl(semid_mutex, 0, SETVAL, arg);
pthread_create(&threads[0],NULL,consumer,NULL);
pthread_create(&threads[1],NULL,producer,NULL);
//remove
semctl(semid_empty, 0 , IPC_RMID, arg);
semctl(semid_full, 0, IPC_RMID,arg);
semctl(semid_mutex, 0 , IPC_RMID, arg);
for(i=0; i<2; i++) {
pthread_join(threads[i],NULL);
}
答案 0 :(得分:1)
在希望此代码可行之前,有一些明显的问题需要修复:
semid_empty
,semid_empty
和semid_empty
是相同的
信号量集,因此所有semop()
操作都在同一个信号量上运行。semop()
失败。semid_full
初始化为0时,代码
错误地使用semid_empty
作为信号量ID。有几种方法可以修复第1项:
为每个信号量集使用不同的键,或者从信号量开始使用
仅在同一过程中使用,您只需使用IPC_PRIVATE
作为关键,例如
semid_empty = semget(IPC_PRIVATE, 1, 0600|IPC_CREAT);
这将确保每个信号量集都是唯一的。
在同一组中创建3个信号量,并将其分配为
空信号量,全信号量和互斥信号量。参考
调用semop()
,semctl
等时的相关信号量。
修复第2项:
第3项可能只是一个错字,修复它:
semctl(semid_full, 0, SETVAL, arg);
最后,这非常重要,为您的代码添加错误检查和记录;大多数问题都会立即显现出来,尤其是semop()
中的setSemaphore()
失败。这会让你自己发现问题。
我不确定修复上述内容是否会修复所有代码问题,或者您的算法是否正确,但这是一个开始,然后您可以尝试添加调试日志记录和错误检查来解决任何其他潜在问题。< / p>