线程同步:
线程最大的特点是资源共享,当多个线程read/write一个文件时,很容易出现读写错误,因此,引入了线程同步。
linux提供了三种方法解决线程同步问题:互斥锁,条件变量,异步信号。
一.互斥锁
首先介绍互斥锁,所为互斥锁,它提供一种机制,使线程在某一时间只能执行一种操作。常用来防止两个进程或线程在同一时刻访问相同的共享资源。
设置互斥琐的步骤为:
1.初始化
初始化有两种方式:
(1)赋值 int pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
(2)函数 int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *mutexattr); //mutexattr表示互斥锁属性
2.加锁
同一时刻,一个线程某一时刻只加一种类型的锁。当一个线程加锁后,其他等待加锁的线程形成等待序列,解锁后按优先级获得锁,并且允许同一个线程对一个锁多次加锁(锁的递归)。
加锁有两种方式,
(1)int pthread_mutex_lock(pthread_mutex_t *mutex); 如果mutex已经加锁,则当前加锁的线程会阻塞,直到互斥锁被其他线程释放。
(2)int pthread_mutex_trylock(pthread_mutex_t *mutex); 如果mutex已经加锁,则该线程立即退出结束。
3.解锁
解锁必须满足
(1)互斥锁处于加锁状态
(2)只能由加锁的线程解锁(谁加谁解);
解锁后等待队列中的第一个线程获得互斥锁.
int pthread_mutex_unlock(pthread_mutex_t *mutex);
4.清除锁
当互斥锁使用完毕后,必须清除。因为互斥锁不占有内存资源,因此清除锁时,只解除斥锁状态,无其他操作。
pthread_mutex_unlock(pthread_mutex_t *mutex);
二.条件变量
条件变量利用线程间共享的全局变量进行同步(类似于if).
条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。
条件变量有两个动作:
1.等待使用资源的线程等待条件变量设置为真;
2.线程使用完资源后设置条件变量为真。
和设置互斥锁一样,设置条件变量有几大步骤:
1.初始化
两种方式:
<1>赋值 pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
<2>函数 pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);
cond_attr 条件变量属性,NULL默认属性
2.等待
(1)无条件等待
pthread_cond_wait(pthread_cond_t *cond);
(2)计时等待
pthread_cond_timewait(thread_cond_t *cond,pthread_mutex_t *mutex,const structtimespec *abstime);
3.解除阻塞
(1)pthread_cond_signal(pthread_cond_t *cond); 解除特定线程阻塞在多个等待队列中按入队顺序激活其中一个。
(2)pthread_cond_broadcast(pthread_cond_t *cond); 解除所有线程阻塞
4.清除条件变量
int pthread_cond_destory(pthread_cond_t *cond); 只有在没有线程等待该条件变量情况下,才能清除。
三。异步信号
在 linux系统中,线程是在内核外实现的(进程在内核中),信号与任何线程都是异步的,
阅读(250) | 评论(0) | 转发(0) |