Chinaunix首页 | 论坛 | 博客
  • 博客访问: 251051
  • 博文数量: 91
  • 博客积分: 4185
  • 博客等级: 上校
  • 技术积分: 855
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-29 16:18
文章分类

全部博文(91)

文章存档

2014年(3)

2013年(1)

2012年(8)

2011年(2)

2010年(5)

2009年(68)

2008年(4)

我的朋友

分类:

2012-09-04 14:43:09

原文地址:Linux线程的同步机制 作者:yulianliu1218

一、互斥量的使用


  1. 可以使用pthread_mutex_init 来动态初始化一个互斥量,在多个线程访问共有数据结构的时候,使用pthread_mutex_lock 加锁,使用之后使用pthread_mutex_unlock解锁;
  2. 互斥量的属性在创建的时候使用的默认属性是PTHREAD_MUTEX_DEFAULT该属性不会进行死锁检查,进行非正常操作的时候会产生undefined behavior;
  3. PTHREAD_MUTEX_NORMAL在对一个已经加锁的互斥量上再次进行加锁操作会导致死锁;
  4. PTHREAD_MUTEX_ERRORCHECK属性提供了错误检查机制以避免死锁,当试图对一个已经加锁(但是没有解锁)的互斥量再次加锁的时候会产生错误。在试图解锁一个未加锁的互斥量或是解锁一个被其他线程加锁使用的互斥量的时候都会产生错误;
  5. PTHREAD_MUTEX_RECURSIVE属性和PTHREAD_MUTEX_ERRORCHECK属性差不多。但是该属性可以提供多次加锁而不会死锁或错误,但需要在解锁的时候做和加锁次数一致的解锁操作;
  6.  设置互斥量的属性需要以下2步操作:
  • 调用pthread_mutexattr_init初始化互斥量属性;
  • 调用pthread_mutexattr_settype设置为想要的属性注意这个函数需要单独使用extern 声明,在 linux线程库中不能使用PTHREAD_MUTEX_ERRORCHECK属性,替换的是PTHREAD_MUTEX_ERRORCHECK_NP;
  • 调用pthread_mutex_init使用设置好的互斥量属性pthread_mutexattr_t,来初始化互斥量pthread_mutex_t;

二、条件变量
  1. 条件变量是需要和互斥量一起配合使用的,互斥量是用来保护条件变量的。其工作的原理是:在一个线程中等待一个条件的成立(未成立之前休眠),在另外一个线程中待条件成立之后唤醒等待的线程和内核中的complete机制类似。
  2. 工作的时候要更改或判断等待条件必须先获取互斥量,其工作顺序是:
    • 首先等待条件成立的线程先调用pthread_mutex_lock锁定保护条件变量的互斥量;
    • 然后判断要等待的条件是否满足,如果满足则进行相关操作然后解锁互斥量;
    • 如果等待的条件不满足调用pthread_cond_wait或pthread_cond_timewait(2者的区别是timewait版本可以指定一个超时时间,在这个时间之内条件不成立,就会返回一个错误不再继续等待)等待条件成立,该数首先会把第1步加锁的互斥量进行解锁操作,然后线程进入阻塞状态,直到超时或是有另外的线程唤醒;
    • 其他的线程获得互斥量操作相关条件,然后调用pthread_cond_signal或是pthread_cond_boardcast(2个函数的区别是第一个函数只会唤醒一个等待的线程,而第二个函数则会唤醒所有等等的线程)函数唤醒等待条件成立的线程,在唤醒其他线程的时候不必在获取互斥量的条件下,但对于可抢占的调度策略来说,最好是在唤醒的时候持有互斥量(对互斥量加锁);
    • 等待条件成立的线程被唤醒(在pthread_cond_wait函数返回之前等待线程会再次获得保护条件变量的锁,原文:Upon successful return, the mutex shall have been locked and shall be owned by the calling thread.),在被唤醒之后等待的线程需要再次判断条件是否成立,因为被唤醒并不意味这条件就成立了(It is thus recommended that a condition wait be enclosed in the equivalent of a "while loop" that checks the predicate.);
  3. 当有多个等待线程阻塞在cond条件变量上的时候,调用pthread_cond_signal函数唤醒的线程是那个取决与内核的的调度策略;
阅读(693) | 评论(0) | 转发(0) |
0

上一篇:编程风格

下一篇:相关链接

给主人留下些什么吧!~~