多线程环境下,如果多个线程对同一共享资源并发访问,那么由于访问资源的时候,由于访问资源的操作的非原子性,可能在向一个buffer写入数据时,另外一个线程也在写入buffer 这时候可能由于两条线程的交替执行的时机的随机性而使得结果每一次运行都不同,这时候就需要操作系统提供的互斥机制来保证某一时刻只有一个线程访问临界区代码,这就是互斥量的语义. 互斥是同步的特殊情况,相当于一个线程告诉另外一个线程,我还在使用资源,请你等到我用完的时候你再来使用资源. 同步的语义就更加大,比如说生产者消费者问题,必须有相应机制告诉生产者停止生产当buffer已经写满的时候,同样当buffer空的时候消费者停止生产.比如说一个队列,当队列为空的时候必须阻塞出队列的操作,当队列者有新的东西的时候唤醒出队操作的线程.
条件变量相当于休眠线程的调用,当队列为空时就就睡眠当前线程,并且将持有的锁释放,以避免死锁.条件变量的第二个参数其实是为了保证workq == NULL 这条语句的正确性,
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
struct msg{
struct msg* next;
int val;
};
struct msg* workq = NULL;
pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;
void process_msg(){
struct msg* mp;
while(1){
sleep(4);
pthread_mutex_lock(&qlock);
while(workq == NULL){
printf("the queue is empty, i am going to sleep and release the mutex\n");
pthread_cond_wait(&qready,&qlock);
}
mp = workq;
workq = mp->next;
pthread_mutex_unlock(&qlock);
printf("the consume is%d\n",mp->val);
}
}
void enqueue_msg(struct msg* mp){
pthread_mutex_lock(&qlock);
mp->next = workq;
workq = mp;
pthread_mutex_unlock(&qlock);
pthread_cond_signal(&qready);
}
void* thread1(void* arg){
process_msg();
}
void* thread2(void* arg){
int i = 0;
while(1){
sleep(5);
struct msg* mp = (struct msg*)malloc(sizeof(struct msg));
mp->next = NULL;
mp->val = i;
i++;
enqueue_msg(mp);
}
}
int main(){
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,thread1,NULL);
pthread_create(&tid2,NULL,thread2,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
}