gpt4 book ai didi

Consumer/Producer多线程同步错误

转载 作者:太空宇宙 更新时间:2023-11-04 03:27:08 27 4
gpt4 key购买 nike

我编写了一个包含四个线程的程序。第一个用于初始化其他缓冲区,第二个用于生成项并将它们添加到缓冲区,第三个用于将项添加到另一个缓冲区,第四个用于使用任一缓冲区中的项。我的问题是第四个线程在写入缓冲槽之前正在读取它们。我已放置信号量以尝试同步,但它们的性能不如我预期。

我在保持错误的同时简化了我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/types.h>

/* thread routines */
void* threadA ();
void* threadB ();
void* threadC ();

/* thread ids */
pthread_t tid[3];

/* semaphores */
sem_t sA;
sem_t sB;
sem_t a_empty;
sem_t b_empty;
sem_t both_full;
sem_t mutex;

/* buffers */
int buffA[20];
int buffB[40];

/* int a for tracking buffA */
int a = 0;

int main()
{

/* initializing semaphores */
sem_init (&a_empty, 20, 1);
sem_init (&b_empty, 40, 1);
sem_init (&both_full, 0, 1);
sem_init (&mutex, 1, 1);
sem_init (&sA, 0, 1);
sem_init (&sB, 0, 1);

/* creating threads */
pthread_create(&tid[0], NULL, threadA, NULL);
pthread_create(&tid[1], NULL, threadB, NULL);
pthread_create(&tid[2], NULL, threadC, NULL);

/* waiting on threads */
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_join(tid[2], NULL);
}

/* Producer */
void* threadA ()
{
int i;
int inA = 0;

/* two process two way synch*/
sem_post(&sB);
sem_wait(&sA);

for (i = 1; i <= 300; i++)
{

/* adding item to buffer */
sem_wait(&a_empty);
buffA[inA] = i;

/* incrementing a */
sem_wait(&mutex);
a = a + 1;
sem_post(&mutex);

/* signaling full buffer */
sem_post(&both_full);

/* updating inA */
inA = (inA + 1) % 20;

}

pthread_exit(NULL);
}

/* Producer */
void* threadB ()
{
int i, j, inB;
inB = 0;

/* two process two way synch*/
sem_post(&sA);
sem_wait(&sB);

for(i = 1; i <= 400; i++)
{

/* producing item. */
sem_wait(&b_empty);
buffB[inB] = i;

sem_post(&both_full);

inB = (inB + 1) % 40;
}

pthread_exit(NULL);
}

/* Consumer */
void* threadC ()
{
int i, j, outA, outB, bsum, asum;
outA = 0;
outB = 0;
asum = 0;
bsum = 0;
int prod_a;
int prod_b;

for(i = 0; i < 700; i++)
{

sem_wait(&both_full);
if (a > 0) {
asum++;
prod_a = buffA[outA];
outA = (outA + 1) % 20;
sem_wait(&mutex);
a = a - 1;
sem_post(&mutex);
sem_post(&a_empty);

printf("A-%d\t", prod_a);
}
else {
bsum++;

prod_b = buffB[outB];
outB = (outB + 1) % 40;
sem_post(&b_empty);

printf("B-%d\t", prod_b);
}
}

printf("\n a=%d b=%d \n", asum, bsum);
pthread_exit(NULL);
}

我的问题似乎是 threadC() 中的 else 语句在不应该执行的时候执行了。我无法确定是什么原因造成的。

编辑:我正在使用 gcc file.c -o file.o -lrt -lpthread 进行编译

最佳答案

信号量 both_full 应该用值 0 初始化:

sem_init (&both_full, 0, 0);

通常,outB 应该总是等于或小于inB。但是当 both_full 初始化为 1 时,threadC() 中的 else 语句在某个点运行而没有可用输入,从而允许增加 outB最多 inB+1。因此,对于前 40 次,您可能会看到零(静态缓冲区在程序启动时归零),此后您可能会看到旧值,例如 B-51 B-52 B-13 B-54

关于Consumer/Producer多线程同步错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40287796/

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