首页 > 代码库 > 【转载】同步和互斥的POSIX支持(互斥锁,条件变量,自旋锁)

【转载】同步和互斥的POSIX支持(互斥锁,条件变量,自旋锁)

上篇文章也蛮好,线程同步之条件变量与互斥锁的结合:
http://www.cnblogs.com/charlesblc/p/6143397.html 
 
现在有这篇文章:
http://blog.csdn.net/goodluckwhh/article/details/8564319
 
POSIX定义了一系列同步对象用于同步和互斥。
同步对象是内存中的变量属于进程中的资源,可以按照与访问数据完全相同的方式对其进行访问。默认情况下POSIX定义的这些同步对象具有进程可见性,即同步对象只对定义它的进程可见;但是通过修改同步对象的属性可以使得同步对象对不同的进程可见,具体的做法是:
  修改同步对象的属性为PTHREAD_PROCESS_SHARED
  在进程的特殊内存区域--共享内存中创建同步对象
 
这样创建的同步对象将对共享该共享内存的所有进程可见,这些进程可以使用该同步对象进行同步互斥。
其中设置共享对象的属性为PTHREAD_PROCESS_SHARED是为了告诉系统该共享对象是跨越进程的,不仅仅对创建它的进程可见;但是仅有这一个条件显然无法满足不同进程使用该同步对象的需求,因为每个进程的地址空间是独立的,位于一个进程的普通内存区域中的对象是无法被其它进程所访问的,能满足这一要求的内存区域是共享内存,因而同步对象要在进程的共享内存区域内创建。
同步对象还可以放在文件中。同步对象可以比创建它的进程具有更长的生命周期。
 
POSIX定义的同步对象包括:
  1. 互斥锁
  2. 条件变量
  3. 自旋锁
  4. 读写锁
  5. 信号量
对于这些同步对象,有一些共同点:
  1. 每种类型的同步对象都有一个init的API,它完成该对象的初始化,在初始化过程中会分配该同步对象所需要的资源(注意是为支持这种锁而需要的资源,不包括表示同步对象的变量本身所需要的内存)
  2. 每种类型的同步对象都一个destory的API,它完成与init相反的工作
  3. 对于使用动态分配内存的同步对象,在使用它之前必须先调用init
  4. 在释放使用动态分配内存的同步对象所使用的内存时,必须先调用destory释放系统为其申请的资源
  5. 每种同步对象的默认作用范围都是进程内部的线程,但是可以通过修改其属性为PTHREAD_PROCESS_SHARED并在进程共享内存中创建它的方式使其作用范围跨越进程范围
  6. 无论是作用于进程内的线程,还是作用于不同进程间的线程,真正参与竞争的都是线程(对于不存在多个线程的进程来说就是其主线程),因而讨论都基于线程来
  7. 这些同步对象都是协作性质的,相当于一种君子协定,需要相关线程主动去使用,无法强制一个线程必须使用某个同步对象

总体上来说,可以将它们分为两类: 

  1. 第一类是互斥锁、读写锁、自旋锁,它们主要是用来保护临界区的,也就是主要用于解决互斥问题的,当尝试上锁时大体上有两种情况下会返回:上锁成功或出错,它们不会因为出现信号而返回另外解锁只能由锁的拥有者进行。
  2. 第二类是条件变量和信号量,它们提供了异步通知的能力,因而可以用于同步和互斥。但是二者又有区别:
    • 信号量可以由发起P操作的线程发起V操作,也可以由其它线程发起V操作;但是条件变量一般要由其它线程发起signal(即唤醒)操作
    • 由于条件变量并没有包含任何需要检测的条件的信息,因而对这个条件需要用其它方式来保护,所以条件变量需要和互斥锁一起使用,而信号量本身就包含了相关的条件信息一般是资源可用量),因而不需要和其它方式一起来使用
    • 类似于三种锁,信号量的P操作要么成功返回,要么失败返回,不会因为出现信号而返回;但是条件变量可能因为出现信号而返回,这也是因为它没包含相关的条件信息而导致的。

【转载】同步和互斥的POSIX支持(互斥锁,条件变量,自旋锁)