我无法理解这段代码的错误。我有一个共享内存分配的共享变量(部分)。当零部分,生产者(厨师)填充锅,消费者(野蛮)消耗部分NROUNDS。我不知道为什么变量部分没有递减。
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/wait.h>
sem_t mutex,empty,full;
int shmid;
int *portions;
void clear() //destroy semaphores and shared memory
{
sem_destroy(&mutex);
sem_destroy(&empty);
sem_destroy(&full);
if (shmctl(shmid,IPC_RMID,0) == -1) perror("shmctl");
}
void producer(int num, int m) //chef that produces portions
{
int i, j;
while(1) {
sem_wait(&mutex); //join critical region
sem_wait(&empty);
*portion=m;
printf("Chef fills the pot\n");
sem_post(&mutex);
sem_post(&full);
}
}
void consumer(int num, int rounds, int m) //savage that consumes portions
{
int i, diff, n, j;
for(i=0;i<rounds;i++) {
sleep(3);
sem_wait(&mutex);
if((*portion)==0) {
sem_post(&empty);
sem_wait(&full);
}
n=rand() % m;
diff=(*portion)-n; //consumes portions
printf("Savage[%d] has eaten %d portions\n", num, diff);
printf("Portions number in pot: %d\n", *portion);
sem_post(&mutex);
}
}
int main(int argc, char *argv[])
{
int i;
int N, M, NROUNDS, pid;
if (argc != 4)
{
fprintf(stderr,"insert N savages, M portions and NROUNDS\n");
exit(1);
}
N=atoi(argv[1]);
M=atoi(argv[2]);
NROUNDS=atoi(argv[3]);
// initialize semaphores and shared memory
sem_init(&mutex,1,1);
sem_init(&empty,1,M);
sem_init(&full,1,0);
shmid = shmget(IPC_PRIVATE,sizeof(int),0600);
if (shmid == -1) perror("Creation shared memory");
portions = (int *) shmat(shmid, NULL, 0);
if (portions == (void *)-1) perror("Attach shared memory");
*portions=M; //initialize shared variable(M is max portions in pot)
/* initialize producer and consumers (1 Producer and N Consumers) */
if (fork()==0)
{ producer(i, M); exit(0);} //producer
for (i = 0; i < N; i++){
if (fork()==0)
{ consumer(i, NROUNDS, M); exit(0);} //consumers
}
for(i=0;i<N;i++) {
pid=wait(NULL);
printf("Terminated process %d\n", pid); //wait terminating processes
}
clear();
}
输出是这样的:
./a.out 3 20 3
Chef fills the pot
Chef fills the pot
Chef fills the pot
Chef fills the pot
Chef fills the pot
Chef fills the pot
Chef fills the pot
Savage[2] has eaten 17 portions
Savage[1] has eaten 17 portions
Savage[0] has eaten 17 portions
Portions number in pot: 20
Portions number in pot: 20
Portions number in pot: 20
Savage[1] has eaten 14 portions
Savage[0] has eaten 14 portions
Savage[2] has eaten 14 portions
Portions number in pot: 20
Portions number in pot: 20
Portions number in pot: 20
Savage[2] has eaten 3 portions
Savage[0] has eaten 3 portions
Savage[1] has eaten 3 portions
Portions number in pot: 20
Portions number in pot: 20
Terminated process 4432
Portions number in pot: 20
Terminated process 4431
Terminated process 4433
答案 0 :(得分:1)
我没有检查整个代码,但看起来好像在这里
n=rand() % m;
代码计算吃掉的部分。
然后在这里计算剩余部分
diff=(*portion)-n;
和错误将它们打印为在这里吃的
printf("Savage[%d] has eaten %d portions\n", num, diff);
代码不会从底池中删除它们(m
)。
要解决此问题
n=rand() % m; // get portions eaten in to n
diff=(*portion)-n; // get the remaining portions
printf("Savage[%d] has eaten %d portions\n", num, n); // log
(*portion) = diff; // or just (*portion) -= n; and drop diff at all.