【发布时间】:2018-10-05 23:54:06
【问题描述】:
有一个生产者-消费者问题是用信号量写的。在下面的代码中,在创建消费者时存在同步执行问题。对于它的解决方案,在消费者的 switch 块中添加了 sleep 语句。
请帮助我提供有效的同步解决方案。任何改进代码的建议都非常有帮助。
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<semaphore.h> /* sem_t */
#include<stdlib.h>
#define BUF_SIZE 2
struct buffer {
int data;
};
struct buffer buf[BUF_SIZE];
sem_t fill, empty;
int value, i;
void *producer(void *data);
void *consumer(void *data);
int main(void)
{
int sel, prod_data, cons_data;
int k;
if (sem_init(&empty, 0, BUF_SIZE)) {
printf("Error: semaphore not initialize\n");
return -1;
}
if (sem_init(&fill, 0, 0)) {
printf("Error: semaphore not initialize\n");
return -1;
}
while (1) {
printf(".........................................................\n");
printf("Selection\n");
printf("Producer : 1 | Consumer : 2 | Display : 3 | Exit : 0 || ");
scanf("%d",&sel);
printf(".........................................................\n");
switch (sel) {
case 1:
sem_getvalue(&empty, &value);
// printf("Prod_e: %d\n", value);
sem_getvalue(&fill, &value);
// printf("Prod_f: %d\n", value);
printf("\nProducer\n");
pthread_t prod_t;
printf("Enter data:");
scanf("%d", &prod_data);
if (pthread_create(&prod_t, NULL, producer, (void *) &prod_data)) {
printf("Error: thread not created\n");
return -1;
}
break;
case 2:
printf("\nConsumer\n");
sem_getvalue(&empty, &value);
// printf("Cons_e: %d\n", value);
sem_getvalue(&fill, &value);
// printf("Cons_f: %d\n", value);
pthread_t con_t;
if (pthread_create(&con_t, NULL, consumer, (void *) &cons_data)) {
printf("Error: thread not created\n");
return -1;
}
if (i == 0) {
printf("Buffer empty\n");
break;
}
// sleep(1); // if commented then synchronization issue
printf("Consume data: %d\n", cons_data);
break;
case 3:
if (i == 0) {
printf("Buffer empty\n");
break;
}
for (k = 0; k < i; k++)
printf("buf[%d]: %d\n", k, buf[k].data);
break;
case 0:
sem_destroy(&fill);
sem_destroy(&empty);
exit (0);
break;
}
}
sem_destroy(&fill);
sem_destroy(&empty);
return 0;
}
void *producer(void *arg)
{
int data = *(int *) arg;
if (sem_wait(&empty)) { /* wait */
printf("Error: sem wait fail\n");
pthread_exit(NULL);
}
buf[i].data = data;
i++;
if (sem_post(&fill)) { /* post */
printf("Error: sem wait fail\n");
pthread_exit(NULL);
}
pthread_exit(NULL);
}
void *consumer(void *arg)
{
if (sem_wait(&fill)) { /* wait */
printf("Error: sem wait fail\n");
pthread_exit(NULL);
}
i--;
*(int *) arg = buf[i].data;
if (sem_post(&empty)) { /* post */
printf("Error: sem wait fail\n");
pthread_exit(NULL);
}
pthread_exit(NULL);
}
没有 sleep 语句的输出:
Selection
Producer : 1 | Consumer : 2 | Display : 3 | Exit : 0 || 1
Producer
Enter data: 11
Selection
Producer : 1 | Consumer : 2 | Display : 3 | Exit : 0 || 3
Display
buf[0] = 11
Selection
Producer : 1 | Consumer : 2 | Display : 3 | Exit : 0 || 2
Consumer
Consume data: 4196464
如果在消费者块中添加睡眠语句,则获得预期的输出(在我们的例子中为 11)。
由于sleep语句的插入,相比switch的case 2语句,消费者线程有足够的时间来完成它的执行并提供预期的输出。
【问题讨论】:
-
能否请您更具体地说明问题?
-
是的 - 怎么会有同步问题?您创建 PC 队列,然后创建生产者/消费者。
-
另请注意:对于多个生产者/消费者安全的有界 PC 队列,您需要两个信号量和一个互斥量(或三个信号量)或等效的 condvar。
标签: c linux multithreading pthreads producer-consumer