Linux C编程--线程操作2--线程同步详解.pdf
《Linux C编程--线程操作2--线程同步详解.pdf》由会员分享,可在线阅读,更多相关《Linux C编程--线程操作2--线程同步详解.pdf(8页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、D DLUTBruceZhang的专栏LUTBruceZhang的专栏 生活就是需要有创意-例如:Coding&Debug生活就是需要有创意-例如:Coding&Debug 置顶置顶 Linux C编程-线程操作2-线程同步详解 Linux C编程-线程操作2-线程同步详解 分类:Linux C编程 2013-03-06 10:21 465人阅读 评论(0)收藏 举报 互斥锁Linux C编程线程同步条件变量信号量 linux线程同步之互斥 在在windows中,为了让多个线程达到同步的目的,在对于全局变量等大家都要用的资源的使中,为了让多个线程达到同步的目的,在对于全局变量等大家都要用的资源
2、的使用上,通常得保证同时只能由一个线程在用,一个线程没有宣布对它的释放之前,不能够给用上,通常得保证同时只能由一个线程在用,一个线程没有宣布对它的释放之前,不能够给其他线程使用这个变量。在其他线程使用这个变量。在windows里,我们可以用时里,我们可以用时EnterCriticalSection()和和LeaveCriticalSection()函数函数.那么在那么在linux里,有什么类似的机制呢?里,有什么类似的机制呢?这里介绍互斥锁。这里介绍互斥锁。1.申请一个互斥锁申请一个互斥锁 pthread_mutex_t mutex;/申请一个互斥锁申请一个互斥锁 你可以声明多个互斥量。你可以
3、声明多个互斥量。在声明该变量后,你需要调用在声明该变量后,你需要调用pthread_mutex_init()来创建该变量。来创建该变量。pthread_mutex_init的的格式如下:格式如下:int pthread_mutex_init(pthread_mutex_t*mutex,const pthread_mutexattr_t*mutexattr);第一个参数,第一个参数,mutext,也就是你之前声明的那个互斥量,第二个参数为该互斥量的属性。,也就是你之前声明的那个互斥量,第二个参数为该互斥量的属性。属性定义如下:属性定义如下:互斥量分为下面三种:互斥量分为下面三种:l 快速型(快速
4、型(PTHREAD_MUTEX_FAST_NP)。这种类型也是默认的类型。该线程的行为)。这种类型也是默认的类型。该线程的行为正如上面所说的。正如上面所说的。l 递归型(递归型(PTHREAD_MUTEX_RECURSIVE_NP)。如果遇到我们上面所提到的死锁情)。如果遇到我们上面所提到的死锁情况,同一线程循环给互斥量上锁,那么系统将会知道该上锁行为来自同一线程,那么就会同况,同一线程循环给互斥量上锁,那么系统将会知道该上锁行为来自同一线程,那么就会同意线程给该互斥量上锁。意线程给该互斥量上锁。l 错误检测型(错误检测型(PTHREAD_MUTEX_ERRORCHECK_NP)。如果该互斥量
5、已经被上)。如果该互斥量已经被上锁,那么后续的上锁将会失败而不会阻塞,锁,那么后续的上锁将会失败而不会阻塞,pthread_mutex_lock()操作将会返回操作将会返回EDEADLK。可以通过函数可以通过函数 注意以下语句可以做到将一个互斥锁快速初始化为快速型。注意以下语句可以做到将一个互斥锁快速初始化为快速型。pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;2.销毁一个互斥锁销毁一个互斥锁 1pthread_mutex_destroy()用于注销一个互斥锁,用于注销一个互斥锁,API定义如下:定义如下:int pthread_mutex_d
6、estroy(pthread_mutex_t*mutex)销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。由于在销毁一个互斥锁即意味着释放它所占用的资源,且要求锁当前处于开放状态。由于在Linux中,互斥锁并不占用任何资源,因此中,互斥锁并不占用任何资源,因此LinuxThreads中的中的pthread_mutex_destroy()除了检查除了检查锁状态以外(锁定状态则返回锁状态以外(锁定状态则返回EBUSY)没有其他动作。)没有其他动作。3.上锁(相当于上锁(相当于windows下的下的EnterCriticalSection)在创建该互斥量之后,你便可以使用它了。要
7、得到互斥量,你需要调用下面的函数:在创建该互斥量之后,你便可以使用它了。要得到互斥量,你需要调用下面的函数:int pthread_mutex_lock(pthread_mutex_t*mutex);该函数用来给互斥量上锁。互斥量一旦被上锁后,其他线程如果想给该互斥量上锁,那么就该函数用来给互斥量上锁。互斥量一旦被上锁后,其他线程如果想给该互斥量上锁,那么就会阻塞在这个操作上。如果在此之前该互斥量已经被其他线程上锁,那么该操作将会一直阻会阻塞在这个操作上。如果在此之前该互斥量已经被其他线程上锁,那么该操作将会一直阻塞在这个地方,直到获得该锁为止。塞在这个地方,直到获得该锁为止。在得到互斥量后,
8、你就可以进入关键代码区了。在得到互斥量后,你就可以进入关键代码区了。4.解锁(相当于解锁(相当于windows下的下的LeaveCriticalSection)在操作完成后,你必须调用下面的函数来给互斥量解锁,也就是前面所说的释放。这样其他在操作完成后,你必须调用下面的函数来给互斥量解锁,也就是前面所说的释放。这样其他等待该锁的线程才有机会获得该锁,否则其他线程将会永远阻塞。等待该锁的线程才有机会获得该锁,否则其他线程将会永远阻塞。int pthread_mutex_unlock(pthread_mutex_t*mutex);5.pthread_mutex_trylock 如果我们不想一直阻塞
9、在这个地方,那么可以调用下面函数:如果我们不想一直阻塞在这个地方,那么可以调用下面函数:int pthread_mutex_trylock(pthread_mutex_t*mutex)如果此时互斥量没有被上锁,那么如果此时互斥量没有被上锁,那么pthread_mutex_trylock()将会返回将会返回0,并会对该互斥量上,并会对该互斥量上锁。如果互斥量已经被上锁,那么会立刻返回锁。如果互斥量已经被上锁,那么会立刻返回EBUSY。注:注:下面介绍一个实例说明上述函数的用法下面介绍一个实例说明上述函数的用法 这是一个简单的读写程序,在这个程序中,一个线程从共享的缓冲区中读数据,另一个线程这是一
10、个简单的读写程序,在这个程序中,一个线程从共享的缓冲区中读数据,另一个线程向共享的缓冲区中写数据。对共享的缓冲区的访问控制是通过使用一个互斥锁来是实现的。向共享的缓冲区中写数据。对共享的缓冲区的访问控制是通过使用一个互斥锁来是实现的。2#include#include#include#include#define FALSE 0#define TRUE 1void readfun();void writefun();char buffer256;int buffer_has_item=0;int retflag=FALSE,i=0;pthread_mutex_t mutex;int main(
11、)void*retval;pthread_t reader;pthread_mutex_init(&mutex,NULL);pthread_create(&reader,NULL,(void*)&readfun,NULL);writefun();pthread_join(reader,&retval);void readfun()while(1)if(retflag)return;pthread_mutex_lock(&mutex);if(buffer_has_item=1)printf(%s,buffer);buffer_has_item=0;pthread_mutex_unlock(&mu
12、tex);void writefun()int i=0;while(1)if(i=10)retflag=TRUE;return;pthread_mutex_lock(&mutex);if(buffer_has_item=0)sprintf(buffer,This is%dn,i+);buffer_has_item=1;pthread_mutex_unlock(&mutex);线程同步之条件变量线程同步之条件变量 与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件
13、变量和互斥锁同时使用。个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。3与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待量进行同步的一种机制,主要包括两个动作:一个线程等
14、待条件变量的条件成条件变量的条件成立立而挂起;另一个线程使而挂起;另一个线程使条件成立条件成立(给出条件成立信号)。(给出条件成立信号)。条件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,条件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量
15、可以被用来实现这两进程间的线程同步。进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步。使用条件变量之前要先进行初始化。可以在单个语句中生成和初始化一个条件变量使用条件变量之前要先进行初始化。可以在单个语句中生成和初始化一个条件变量如:如:pthread_cond_t my_condition=PTHREAD_COND_INITIALIZER;(用于进程间线程的通信)。可以利用函数(用于进程间线程的通信)。可以利用函数pthread_cond_init动态初始化。动态初始化。条件变量分为两部分条件变量分为两部分:条件和变量条件和变量.条件本身是由互斥量保护的条件本身是由互斥量保护
16、的.线程在改变条件状线程在改变条件状态前先要锁住互斥量态前先要锁住互斥量.它它利用线程间共享的全局变量进行同步的一种机制。利用线程间共享的全局变量进行同步的一种机制。相关的函数如下:相关的函数如下:1 1intintpthread_cond_init(pthread_cond_tpthread_cond_init(pthread_cond_t*cond,pthread_condattr_t*cond,pthread_condattr_t*cond_at*cond_attr);tr);2 2intintpthread_cond_wait(pthread_cond_tpthread_cond_wa
17、it(pthread_cond_t*cond,pthread_mutex_t*cond,pthread_mutex_t*mutex);*mutex);3 3intintpthread_cond_timewait(pthread_cond_tpthread_cond_timewait(pthread_cond_t*cond,pthread_mutex*cond,pthread_mutex*mutex,co*mutex,constnsttimespectimespec*abstime);*abstime);4 4intintpthread_cond_destroy(pthread_cond_tpt
18、hread_cond_destroy(pthread_cond_t*cond);*cond);5 5intintpthread_cond_signal(pthread_cond_tpthread_cond_signal(pthread_cond_t*cond);*cond);6 6intintpthread_cond_broadcast(pthread_cond_tpthread_cond_broadcast(pthread_cond_t*cond);*cond);/觩陪扆朏绅稑皊陁/觩陪扆朏绅稑皊陁塤塤 简要说明:简要说明:(1)初始化.init()或者pthread_cond_t cond
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux C编程-线程操作2-线程同步详解 编程 线程 操作 同步 详解
限制150内