2014-05-06 13 views
0

不知道消费者为什么做所有的工作?带信号和叉的产品消费者

我为产品为10个整数的数组创建了一个semaphor,该数组填充了名称,并且返回1和0(二进制)。即使生产者正在释放信号,也会调用消费者。

为什么会发生这种情况?

这是代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <semaphore.h> 
#include <fcntl.h> 
#define SIZE 10 
#define KEY 1234 
int *Memory; 
int i, j; 
sem_t *sem; 
char *name = "Hello"; 
int main(int argc, const char *argv[]) 
{ 
    int shmid; 
    if ((shmid = shmget(KEY, sizeof(int) * SIZE, IPC_CREAT | S_IRWXU)) < 0) 
    { 
     perror("Error while creating shmget"); 
     return 1; 
    } 
    pid_t pid; 
    sem = sem_open(name, O_CREAT, S_IRUSR | S_IWUSR, 1); 
    if ((pid = fork()) != 0) 
    { 
     if ((shmid = shmget(KEY, sizeof(int) * SIZE, S_IRWXU)) < 0) 
     { 
      perror("error in shmget"); 
      return 1; 
     } 
     Memory = (int *)shmat(shmid, NULL, 0); 
     if (Memory == NULL) 
     { 
      perror("error in shmat"); 
      return 1; 
     } 
     for (i = 0; i < 10; i++) 
     { 
      sem_wait(sem); 
      Memory[j] = i; 
      printf("Produced %i in box %i\n", i + 1, i + 1); 
      sem_post(sem); 
      sleep(1); 
     } 
     int status; 
     wait(&status); 
     sem_unlink(name); 
     sem_destroy(sem); 
     struct shmid_ds shmid_ds1; 
     if (shmctl(shmid, IPC_RMID, &shmid_ds1) < 0) 
     { 
      perror(
       "Error in the father while executing shmctl when it was " 
       "elimnating the segment of shared memory"); 
     } 
    } 
    else 
    { 
     if ((shmid = shmget(KEY, sizeof(int) * SIZE, S_IRWXU)) < 0) 
     { 
      perror("error in the producer with the shmget"); 
      return 1; 
     } 
     Memory = (int *)shmat(shmid, NULL, 0); 
     if (Memory == NULL) 
     { 
      perror("error in the producer with the shmat"); 
      return 1; 
     } 
     for (i = 0; i < 10; i++) 
     { 
      sem_wait(sem); 
      Memory[i] = -1; 
      printf("Consume and now it is %i in box %i\n", Memory[i], i + 1); 
      sem_post(sem); 
     } 
    } 
    return 0; 
} 

,输出是:

Produced 1 in box 1 
Consume and now it is -1 in box 1 
Consume and now it is -1 in box 2 
Consume and now it is -1 in box 3 
Consume and now it is -1 in box 4 
Consume and now it is -1 in box 5 
Consume and now it is -1 in box 6 
Consume and now it is -1 in box 7 
Consume and now it is -1 in box 8 
Consume and now it is -1 in box 9 
Consume and now it is -1 in box 10 
Produced 2 in box 2 
Produced 3 in box 3 
Produced 4 in box 4 
Produced 5 in box 5 
Produced 6 in box 6 
Produced 7 in box 7 
Produced 8 in box 8 
Produced 9 in box 9 
Produced 10 in box 10 

回答

1
#include <pthread.h> 
#include <stdio.h> 
#include <semaphore.h> 
const int max = 5; 
int arr[5], f = 0, r = -1; 
sem_t s1, s2, sm; 
void* eprod(void* pv) 
{ 
    int i, x; 
    printf("Producer Welcome\n"); 
    // sleep(10); 
    while (1) 
    { 
     x = rand() % 100; 
     printf("producer going to add:%d\n", x); 
     sem_wait(&s2); 
     sem_wait(&sm); 
     // down s2 //buffer may be full 
     // lock sm 
     r = (r + 1) % max; 
     arr[r] = x; 
     sem_post(&sm); 
     sem_post(&s1); 
     sleep(10); 
    } 
    // unlock sm 
    // up s1 
} 
void* econs(void* pv) 
{ 
    int i, x; 
    printf("Consumer Welcome\n"); 
    while (1) 
    { 
     sem_wait(&s1); 
     sem_wait(&sm); 
     // down s1 
     // lock sm 
     x = arr[f]; 
     f = (f + 1) % max; 
     printf("Consumer removed element:%d\n", x); 
     sem_post(&sm); 
     sem_post(&s2); 
     // unlock sm 
     // up s2 
     // sleep(5); 
    } 
} 
int main() 
{ 
    pthread_t pt1, pt2; 
    sem_init(&s1, 0, 0); // 3rd Parameter ival=1 
    sem_init(&s2, 0, max); // 3rd Parameter ival=1 
    sem_init(&sm, 0, 1); // 3rd Parameter ival=1 
    pthread_create(&pt1, NULL, eprod, (void*)0); 
    pthread_create(&pt2, NULL, econs, (void*)1); 
    printf("Main Thread is Running\n"); 
    pthread_join(pt1, NULL); 
    pthread_join(pt2, NULL); 
    printf("Main -- - - Thanks..!\n"); 
    return 0; 
} 

希望这有助于..

+0

谢谢@ user2485710我已经使用线程来解决问题,并且完美地工作。但是你知道我怎么能用信号量和叉子来解决消费者生产? – user3606231

+0

@ user3606231右侧的名称是发布帖子的用户的名称,我刚刚编辑它以修复缩进。 – user2485710

0

你的输出是与你的程序代码是一致的。 您的两个进程都使用信号量来访问共享内存块,因此它们通过相互排斥工作,即在任何给定时间只允许其中一个使用Memory[]阵列。

但是你的程序没有任何东西可以进一步限制进程的行为,所以消费者有可能在没有生产者做任何事情的情况下继续进行。

您需要在您的程序中引入更多簿记来处理Memory[]阵列中的保留/空闲插槽,以及两个用于同步生产者和消费者进度的信号灯。查看有关问题的任何标准解决方案,例如http://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem#Using_semaphores