1.条件变量是锁吗?
不是锁,但是条件变量能够阻塞线程
条件变量需要和互斥锁一起使用
互斥量:保护一块共享数据
条件变量:引起阻塞
2.条件变量的两个动作?
当条件满足,通知阻塞的线程线程开始工作
条件不满足,阻塞线程
3.条件变量的类型
pthread_cond_t;
4.主要函数
初始化一个条件变量
pthread_cond_init(
phtread_cond_t* restrict cond,
xonst pthread_condattr_t* restrict attr
);
销毁一个条件变量
pthread_cond_destroy(pthread_cond_t * cond);
阻塞等待一个条件变量
pthreaa_cond_wait(
pthread_cond_t *restrict cond,
pthread_mutex_t * restrict mutex
);
阻塞线程,将已经上锁的mutex解锁,该函数接触阻塞的时候,对互斥锁继续加锁
限时等待一个条件变量
pthread_cond_timedwait(
pthread_cond_t *restrict cond,
pthread_mutex_t* restrict mutex;
const struct timespec* abstime
)
唤醒至少一个阻塞在条件变量上的线程
pthread_cond_signal(pthread_cond_t* cond);
唤醒全部阻塞在条件变量上的线程
pthread_cond_broadcast(pthread_cond_t* cond);
我们用生产者和消费者来理解条件变量,当没有产品可消费时,条件变量就会阻塞消费者这边,等待生产者生产,当生产者生产出东西时,条件变量就会告诉消费者有东西可以消费了,消费者继续消费。我们通过一段代码来理解
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
//线程同步需要互斥锁
pthread_mutex_t mutex;
//阻塞线程需要条件变量
pthread_cond_t cond;
typedef struct Node
{
int data;
struct Node *next;
}Node;
Node* head = NULL;
void * producer()
{
while(1)
{
Node *p = (Node *)malloc(sizeof(Node));
p->data = rand()%1000;
//开始枷锁,保护共享资源
pthread_mutex_lock(&mutex);
p->next = head;
head = p;
//开始解锁
printf("producer pthid = %lu,%d\n",pthread_self(),p->data);
pthread_mutex_unlock(&mutex);
//通知阻塞的线程
pthread_cond_signal(&cond);
sleep(rand()%3);
}
return NULL;
}
void * customer()
{
while(1)
{
//枷锁
pthread_mutex_lock(&mutex);
if(head == NULL)
{
//continue;
//在这里做了三件事情阻塞线程,对互斥锁解锁,让生产者那边加锁,生产出东西后返回回来又对互斥锁继续枷锁
pthread_cond_wait(&cond,&mutex);
}
printf("sustomer pthid = %-lu,%d\n",pthread_self(),head->data);
Node*p = head->next;
free (head);
head = p;
//解锁
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main()
{
//创建两个线程,一个生产,一个消费
pthread_t p1,p2;
pthread_create(&p1,NULL,producer,NULL);
pthread_create(&p2,NULL,customer,NULL);
//初始化条=条件变量和互斥锁
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
//回收子线程
pthread_join(p1,NULL);
pthread_join(p2,NULL);
//销毁条件变量和互斥锁
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}