线程条件变量 生产者消费者模型 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)!