Linux C语言 生产者消费者模型 条件变量互斥锁实现

生产者消费者模型

生产者消费者模型是线程同步的典型案例,而借助条件变量来实现这一模型,是一种比较常见的做法。

假定有两个线程,一个模拟生产者行为,一个模拟消费者行为。两个线程同时操作一个共享资源(一般称之为汇聚),生产向其中添加产品,消费者从中消费掉产品。
Linux C语言 生产者消费者模型 条件变量互斥锁实现_第1张图片

程序实现

#include 
#include 
#include 
#include 

typedef struct MSG{
    struct MSG* next;
    struct MSG* pre;
    int id;
}msg_t;

msg_t *phead = NULL, *ptail = NULL;

// 静态初始化 也可以用pthread_cond_init(&hasproduct, NULL); 进行初始化
pthread_cond_t hasproduct = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// 生产者
void* productor(void *p)
{
    msg_t* mg = NULL;
    while(1){
        pthread_mutex_lock(&lock);
		// 生产产品
        mg = (msg_t*)malloc(sizeof(msg_t));
        scanf("%d", &mg->id);
        printf("product id = %d\n",mg->id);
		// 加入到生产队列里面
        mg->next = NULL;
        mg->pre = ptail;
        ptail->next = mg;
        ptail = mg;

        pthread_mutex_unlock(&lock);
        // 唤醒至少一个阻塞在条件变量上的线程
        pthread_cond_signal(&hasproduct);
    }
    return NULL;
}

// 消费者
void* consumer(void *p)
{
    msg_t* mg = NULL;
    while(1){
        pthread_mutex_lock(&lock);
        while(phead == ptail){ // 注意这里不能是 if 因为会有多个消费者争夺支援
        	// 当队列没有产品的时候会阻塞且释放锁(unlock)直到被唤醒
        	// 有产品被唤醒的时候会返回且重新获得锁(lock)
            pthread_cond_wait(&hasproduct, &lock);
        }
        printf("consume id = %d\n", ptail->id);
		// 消费一个产品
        ptail = ptail->pre;
        free(ptail->next);
        ptail->next = NULL;

        pthread_mutex_unlock(&lock);
    }
    return NULL;
}

int main()
{
    phead = (msg_t*)malloc(sizeof(msg_t));
    ptail = phead;
    pthread_t pid, cid;

    pthread_create(&pid, NULL, productor, NULL);
    pthread_create(&cid, NULL, consumer, NULL);
	
    pthread_join(pid, NULL);
    pthread_join(cid, NULL);

    return 0;
}

注意:生产者和消费者往往有多个,这里为了简化就只设计了一个。

你可能感兴趣的:(多线程,多线程,队列,c++)