(一)互斥量作用
1、保护不安全的库函数。
说一个函数是线程安全的,意思是同一时刻可以被多个线程安全调用,而不会发生脏数据之类的事情
pthread_mutex_lock(&mutex)
unsafe_function()//调用不安全的库函数
pthread_mutex_unlock(&mutex)
2、对标志符和全局变量进行同步
同上,只是把库函数修正为标志符和变量
只能短时间持有,等待输入这样的持续时间不确定的情况,用条件变量来同步。
(二)条件变量
为什么会有条件变量,忙等可能使得其他的线程不能得到cpu。
对信号量的理解,可以参照mutex,mutex的值为1或者0(lock为1,unlock为0)。而信号量是wait到的时候sem-1,等sem减小到0就挂起,post的时候sem+1,并唤起挂起的线程。附上一则例子
/*
*生产者消费者关于信号的例子
*通过两个信号量,一个blank 一个product。生产前先将blank -1(sem_wait) ,减少到0就挂起
*product就+1(sem_post),唤起挂起等待的线程
*
*这里应该也可以使用一个信号量来完成这个例子
*/
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <stdio.h>
#define NUM 5
int queue[NUM];
sem_t blank_number,product_number;
void* producer(void* arg)
{
int p=0;
while(1)
{
sem_wait(&blank_number);
queue[p]=rand()%1000 +1;
printf("produce id=%d,value=%d\n",p,queue[p]);
sem_post(&product_number);
p=(p+1)%NUM;
sleep(rand()%3);
}
}
void* consumer(void* arg)
{
int c=0;
while(1)
{
sem_wait(&product_number);
printf("=========================consumer id=%d,value=%d\n",c,queue[c]);
queue[c] = 0;
sem_post(&blank_number);
c=(c+1)%NUM;
sleep(rand()%3);
}
}
int main(int argc,char* argv[])
{
pthread_t tid_p,tid_c;
int ret_p,ret_c;
sem_init(&blank_number,0,NUM);
sem_init(&product_number,0,0);
ret_p = pthread_create(&tid_p,NULL,producer,NULL);
if(ret_p != 0)
printf("pthread create error\n");
ret_c = pthread_create(&tid_c,NULL,consumer,NULL);
if(ret_c != 0)
printf("pthread consumer create error\n");
pthread_join(tid_p,NULL);
pthread_join(tid_c,NULL);
sem_destroy(&blank_number);
sem_destroy(&product_number);
exit(0);
}
(四)读写锁
也叫共享-独占锁。
当读写锁是写加锁状态时,在解锁之前试图对这个锁加锁的线程都会被阻塞。
当读写锁是读加锁状态时,所有以读模式对他进行加锁的线程都可以得到访问权;所有希望以写模式对此锁进行加锁的线程,必须阻塞直到所有的线程释放读锁(这种情况下读写锁通常会阻塞随后的读模式锁请求,避免读模式锁长期占用,而等待的写模式所请求得不到满足)。
描
述
|
POSIX 函数
|
互斥锁
pthread_mutex_t
|
pthread_mutex_destroy
pthread_mutex_init
pthread_mutex_lock
pthread_mutex_trylock
pthread_mutex_unlock
|
条件变量
|
pthread_cond_destroy
pthread_cond_init
pthread_cond_broadcast
pthread_cond_signal
pthread_cond_timewait
pthread_cond_wait
|
读--写锁
|
pthread_rwlock_destroy
pthread_rwlock_init
pthread_rwlock_rdlock
pthread_rwlock_wrlock
pthread_rwlock_timedrdlock
pthread_rwlock_timewrlock
pthread_rwlock_tryrdlock
pthread_rwlock_trywrlock
|
(五)效率问题
明显的使用同步这些机制会给程序的运行带来负担,总体感觉结合条件变量就比单纯的使用mutex效率高些,真正的效率如何我没能找到资料证实。留待以后查证或者验证。
之前对线程同步这一块比较敬畏,老感觉吃不透。事实上这一块也算是比较难用的。实际的工作中对同步还是接触到的比较少,之前写的类似网关的程序虽然也是多线程并发,但是需要同步的处理也是比较少。现在接触的软件模型中数据库这种多种用户实时读写的应用比较需要。而用户之间交互比较少的应用模型就很少用到这些了。