生产者消费者问题中的竞争状况

时间:2018-10-28 13:45:09

标签: c pthreads semaphore race-condition producer-consumer

在下面的代码中,我希望print语句将始终打印$SearchTag = Tag::where(function($query) { $query->orWhere('tag', 'like', 'veritatis%'); $query->orWhere('tag', 'like', 'rem%'); })->with('search_Tags')->get(); $uniqueTags = $SearchTag->unique('tag'); return response($uniqueTags); (因为它是二进制信号量,并且已经获得了锁)。

s=0

但是输出是

/// Producer Consumer problem using semaphores

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>

#define BUFF_SIZ 10

int s = 1; /// binary semaphore
int full = 0;
int empt = BUFF_SIZ;

int arr[BUFF_SIZ];
int value = 100;

void wait(int *s)
{
    while(*s <= 0);
    *s = *s - 1;
}
void signal(int* s)
{
    *s = *s + 1;
}
void *producer(void* param)
{
    for(int i=0;i<BUFF_SIZ;i++)
    {
        int new_item = value;
        value++;
        wait(&empt);
        wait(&s);

        printf("s = %d\n",s);
        printf("Producer inside critical section\n");
        printf("Produced item = %d\n\n",new_item);
        arr[i] = new_item;

        signal(&s);
        signal(&full);
    }
    pthread_exit(0);
}
void *consumer(void* param)
{
    for(int i=0;i<BUFF_SIZ;i++)
    {
        wait(&full);
        wait(&s);

        printf("s = %d\n",s);
        printf("Consumer inside critical section\n");
        printf("Consumed item = %d\n\n", arr[i]);

        signal(&s);
        signal(&empt);
    }
    pthread_exit(0);
}
int main()
{
    pthread_t tid_p,tid_c;
    pthread_attr_t attr1,attr2;
    pthread_attr_init(&attr1);
    pthread_attr_init(&attr2);

    pthread_create(&tid_p,&attr1,producer,NULL);
    pthread_create(&tid_c,&attr2,consumer,NULL);

    pthread_join(tid_p,NULL);
    pthread_join(tid_c,NULL);
    return 0;
}

因此,根据我的说法,这是由于s = 0 Producer inside critical section Produced item = 100 s = 0 Producer inside critical section Produced item = 101 s = 0 Producer inside critical section Produced item = 102 s = -1 Consumer inside critical section Consumed item = 100 s = 0 Producer inside critical section Produced item = 103 s = 0 Producer inside critical section Produced item = 104 s = -1 Consumer inside critical section Consumed item = 101 s = 0 Consumer inside critical section Consumed item = 102 s = 0 Consumer inside critical section Consumed item = 103 s = 0 Consumer inside critical section Consumed item = 104 s = -1 Producer inside critical section Produced item = 105 s = 0 Producer inside critical section Produced item = 106 s = 0 Producer inside critical section Produced item = 107 s = -1 Consumer inside critical section Consumed item = 105 s = 0 Consumer inside critical section Consumed item = 106 s = 0 s = 0 Producer inside critical section Produced item = 108 s = 0 Producer inside critical section Produced item = 109 Consumer inside critical section Consumed item = 107 s = 1 Consumer inside critical section Consumed item = 108 s = 1 Consumer inside critical section Consumed item = 109 函数的非原子操作引起的竞态条件(让我知道我是否错了)。有什么办法可以避免这种情况?

1 个答案:

答案 0 :(得分:0)

您可以尝试用一些伪信号量替换s,完整的空整数:

struct pseudo_sem {
    int value; /// binary semaphore
    pthread_mutex_t mutex;
};
struct pseudo_sem s = { 1, PTHREAD_MUTEX_INITIALIZER };
struct pseudo_sem full = { 0, PTHREAD_MUTEX_INITIALIZER };
struct pseudo_sem empt = { BUFF_SIZ, PTHREAD_MUTEX_INITIALIZER };

void wait(struct pseudo_sem *s)
{
    pthread_mutex_lock(&s->mutex);
    while(s->value <= 0) {
        pthread_mutex_unlock(&s->mutex);
        usleep(100); // be kind, sleep a bit
        pthread_mutex_lock(&s->mutex);
    }   
    s->value--;
    pthread_mutex_unlock(&s->mutex);
}

void signal(struct pseudo_sem* s)
{
    pthread_mutex_lock(&s->mutex);
    s->value++;
    pthread_mutex_unlock(&s->mutex);
}

这可能有效,但是会执行繁忙的循环,而真正的信号量则无法做到这一点,这就是为什么使用真实的信号量更好的恕我直言