条件变量
读写锁与互斥锁的缺点:
不是什么时候都能阻塞线程
只能够保证共享资源在什么时候被阻塞
条件变量
能够在不满足条件的时候阻塞线程
当条件满足,通知阻塞线程开始工作
要实现线程同步与共享资源,还得跟互斥锁一起使用
生产者消费者模型
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <pthread.h>
typedef struct node{
int data;
struct node* next;
}Node;
///< 永远指向链表头部的指针
Node * head = NULL;
///< 线程同步,互斥锁
pthread_mutex_t mutex;
///< 条件变量
pthread_cond_t cond;
void *producer (void* arg)
{
while (1)
{
///< 创建一个链表的节点
Node* pnew = (Node*)malloc (sizeof(Node));
pnew->data = rand() % 1000;
///< 加锁
pthread_mutex_lock (&mutex);
pnew->next = head;
head = pnew;
printf ("======Pruducer : %lu, %d\n", pthread_self(),
pnew->data);
pthread_mutex_unlock (&mutex);
///< 通知阻塞的消费者线程解除阻塞
pthread_cond_signal(&cond);
sleep(rand() % 3);
}
return NULL;
}
void *customer(void *arg)
{
while (1)
{
pthread_mutex_lock (&mutex);
if (head == NULL)
{
///< 该函数会对互斥锁解锁
pthread_cond_wait (&cond, &mutex);
///< 解除阻塞时会做加速操作
}
Node* pdel = head;
head = head->next;
printf ("-------consumer : %lu, %d\n", pthread_self(),
pdel->data);
free (pdel);
pthread_mutex_unlock (&mutex);
}
return NULL;
}
int main (int argc, const char* argv[])
{
pthread_t p1, p2;
///< 锁
pthread_mutex_init (&mutex, NULL);
pthread_cond_init (&cond, NULL);
///< 生产者
pthread_create(&p1, NULL, producer, NULL);
///< 消费者
pthread_create(&p2, NULL, customer, NULL);
///< 阻塞回收子线程
pthread_join(p1, NULL);
pthread_join(p2, NULL);
///< 销毁锁
pthread_mutex_destroy (&mutex);
pthread_cond_destroy(&cond);
return 0;
}
信号灯
头文件 semaphore.h
互斥锁mutex实现的同步都是串行的
信号量可以运行多个线程访问共享资源