我编写了一个由四个线程组成的程序。第一个用于初始化其他项,第二个用于生成项并将它们添加到缓冲区,第三个用于将项添加到另一个缓冲区,第四个用于从任一缓冲区中使用项。我的问题是第四个线程在写入之前从缓冲区槽读取。我已经设置信号量以尝试同步,但它们没有像我期望的那样执行。
我在保持错误的同时简化了我的代码:
#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
来编译
答案 0 :(得分:1)
信号量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 < / p>