gpt4 book ai didi

c - C 中使用信号量的生产者-消费者

转载 作者:行者123 更新时间:2023-11-30 19:30:49 25 4
gpt4 key购买 nike

使用信号量编写存在生产者-消费者问题。在下面的代码中,创建消费者时存在同步执行问题。对于其解决方案,在消费者的 switch block 中添加 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

如果在消费者 block 中添加 sleep 语句,则获得预期输出(在我们的例子中为 11)。
与 switch 的 case 2 语句相比,由于 sleep 语句插入,消费者线程有足够的时间来完成其执行并提供预期的输出。

最佳答案

问题是您的主线程运行到显示消费者线程应该“返回”的数据的位置。但主线和消费者之间没有同步。

最简单的解决方案(仍然使用线程)是让主线程加入消费者线程 - 这就是它如何知道消费者已经完成其工作。不要调用 sleep ,而是尝试:

pthread_join(con_t, NULL);

实际上,您在 Producer() 线程中存在类似的同步问题,只是它并不明显,因为在获得更多输入之前,您不会对生成线程更新的数据执行任何操作。因此,竞争条件有足够的时间来完成,以产生您期望的结果。

但是,请记住,您的程序实际上并没有利用并发性 - 它创建线程,但不并行执行任何重要的工作。您也可以直接调用 Producer() Consumer()

关于c - C 中使用信号量的生产者-消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50023380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com