自学内容网 自学内容网

线程条件变量 生产者消费者模型 Linux环境 C语言实现

只能用来解决同步问题,且不能独立使用,必须配合互斥锁一起用


头文件:#include <pthread.h>
类型:pthread_cond_t
PTHREAD_COND_INITIALIZER 初始化
初始化:int pthread_cond_init(pthread_cond_t * cond, NULL);
清理:int pthread_cond_destroy(pthread_cond_t * cond);
P操作: 
     int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t *mutex);//mutex必须是pthread_mutex_lock返回后的
V操作: int pthread_cond_signal(pthread_cond_t * cond);//只是出队任务等待队列中的第一个任务,让该任务正在阻塞的P操作返回
V操作: int pthread_cond_broadcast(pthread_cond_t * cond);//出队任务等待队列中的所有任务,让所有正阻塞的任务的P操作返回

功能:见函数名
返回值:成功0,失败错误码
mutex为已经处于锁状态的互斥锁,因此条件变量必须与一个互斥量配合使用


代码模板:

代码模板:
pthread_cond_t cond;
pthread_mutex_t lock;

程序开始时:
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&cond,NULL);

程序结束前:
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);

A线程为先做线程
pthread_mutex_lock(&lock);
....
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond);


B线程为后做线程
pthread_mutex_lock(&lock);
if(条件表达式为真)
{
pthread_cond_wait(&cond,&lock);
}
.....
pthread_mutex_unlock(&lock);

生产者消费者模型(生产者生产出来东西后消费者才能执行)

问题:设计程序,一个线程实现入队操作,另一个实现出队操作, 如果队列中没有数据,出队线程不参与资源的竞争.(条件变量)
代码:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>

#if  0
条件变量在生产者消费者模型中使用步骤:
1、定义条件变量和互斥锁,并初始化

消费者线程:
1、加锁
 int pthread_mutex_lock(pthread_mutex_t *mutex);

2、判断公共资源中是否有数据
while(公共资源中没有数据成立)
{
    //造成线程的阻塞,在阻塞之前进行解锁
    //被唤醒后,申请加锁
    int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

}

3、如果公共资源中有数据, 消费数据


4、解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);


生产者线程:
1、加锁
 int pthread_mutex_lock(pthread_mutex_t *mutex);

2、生产数据, 并放到公共资源中

3、解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);

4、发送信号给条件变量, 唤醒所有阻塞在条件变量上的线程
  int pthread_cond_signal(pthread_cond_t *cond);

#endif

struct  node{
    int data;
    struct node *next;
};

pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 初始化cond条件变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 初始化mutex锁

struct node *head = NULL;

//生产者线程
void* product(void* argv){
    struct node *pnew = NULL;
    // sleep(10);
    while(1){
        pnew = malloc(sizeof(struct node));
        assert(pnew != NULL);

        pnew->data = rand();
        pnew->next = NULL;

        printf("========product: %d\n", pnew->data);

        pthread_mutex_lock(&mutex); // 上锁

        pnew->next = head;
        head = pnew;

        pthread_mutex_unlock(&mutex); // 解锁

        pthread_cond_signal(&cond); // 发出信号

        sleep(1);
    }

    return NULL;
}

//消费者线程
void*  consumer(void* argv){
    struct node *pdel = NULL;
    while(1){
        pthread_mutex_lock(&mutex); // 上锁

        while(NULL == head){ // 判断条件是否满足
            printf("wait..\n");
            pthread_cond_wait(&cond, &mutex); // 解锁等待,条件满足后再上锁
            printf("wait  over...\n");
        }
        printf("------->consumer: %d\n", head->data);
        pdel = head;
        head = head->next;
        free(pdel);

        pthread_mutex_unlock(&mutex); // 解锁

        sleep(1);
    }
    return NULL;
}


int main(){
    pthread_t  pth1, pth2;

    if(0 != pthread_create(&pth1, NULL, product, NULL)){
       perror("pthread_create");
       return -1;
    }

    if(0 != pthread_create(&pth2, NULL, consumer, NULL)){
       perror("pthread_create");
       return -1;
    }

    pthread_join(pth1, NULL); // 回收线程
    pthread_join(pth2, NULL);

    pthread_mutex_destroy(&mutex); // 销毁锁
    pthread_cond_destroy(&cond); // 销毁条件变量

    return 0;
}

输出:


原文地址:https://blog.csdn.net/2301_77329667/article/details/144252501

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!