有关互斥量

原创 2012年03月27日 21:12:41
创建和销毁互斥量

pthread_mutex_t_mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

大部分时间你可能在"文件范围"内,即函数体外,声明互斥量为外部或静态存储类型。如果有其他文件使用互斥量,即将其声明为外部类型;如果仅在本文件中使用,则将其声明为静态类型。应该使用宏PTHREAD_MUTEX_INITIALIZER来声明具有默认属性的静态互斥量。

通常不能静态地初始化一个互斥量,如使用malloc动态分配一个包含互斥量的数据结构时。这时,应该使用pthread_mutex_init调用来动态地初始化互斥量。也可以动态地初始化静态声明的互斥量,但必须保证每个互斥量在使用前被初始化,而且只被初始化一次。可以在创建任何线程之前初始化它,如通过调用pthread_once。若需要初始化一个非缺省属性的互斥量,必须使用动态初始化。
当不再需要一个通过pthread_mutex_init调用动态初始化的互斥量时,应该调用pthread_mutex_destroy来释放它。不需要释放一个使用PTHREAD_MUTEX_INITIALIZER宏静态初始化的互斥量。

加锁和解锁互斥量
int pthread_mutex_lock (pthread_mutex_t *mutex);
int pthread_mutex_trylock (pthread_mutex_t *mutex);
int pthread_mutex_unlock (pthread_mutex_t *mutex);

当调用线程已经锁住互斥量之后,就不能再加锁该互斥量。试图这样做的结果可能是返回错误(EDEADLK), 或者可能陷入"自死锁",使不幸的线程永远等待下去。不能解锁一个已经解锁的互斥量,也不能解锁由其他线程锁住的互斥量。锁住的互斥量是属于加锁线程的。

sched_yield效果:将处理器交给另一个等待运行的线程,但是如果没有就绪的线程,就立即返回。

当需要保护两个共享变量时,有两种基本策略:可以为每个变量指派一个“小”互斥量,或为两个变量指派一个“大”的互斥量。哪一种方法更好取决于很多因素。以下是主要的设计因素:
1 互斥量不是免费的,需要时间加锁和解锁。互斥量应该尽量少,够用即可,每个互斥量保护的区域则尽量大。
2 互斥量的本质是串行执行。若很多线程需要频繁地加锁在同一个互斥量,则线程的大部分时间就会在等待,这对性能是在害的。如果互斥量保护的数据包含彼此无关的片段,则可以将大的互斥量分解为几个小的互斥量来提高性能。这样,任意时刻需要小互斥量的线程减少,线程等待的时间就会减少。所以,互斥量应该足够多(到有意义的地步),每个互斥量保护的区域则应尽量的少。

使用多个互斥量:同时使用多个互斥量会导致复杂度的增加。最坏的情况就是死锁的发生,即两个线程分别锁住一个互斥量而等待对方的互斥量。更多的是像优先级倒置这样的微妙问题(当你将互斥量和优先级调用组合使用时)。

加锁层次:若可以在独立的数据上使用两个分离的互斥量,那么就应该这样做。这样,通过减少线程必须等待其他线程完成数据操作(甚至是该线程不需要的数据)的时间。若数据独立,则某个特定函数就不太可能经常需要同时加锁两个互斥量。
当数据不是完全独立的时候,情况就复杂了。如果你的程序有一个不变量,影响着由两个互斥量保护的数据,即使该不变量被改变或引用,你迟早需要编写同时锁住两个互斥量的代码,来确保不变量的完整。

两个锁的死锁:
有互斥量A B 若一个线程锁住互斥量A后,加锁互斥量B;同时,另一个线程锁住B而等待A,则代码就产生了一个经典的死锁现象。

针对死锁有解决方法:
固定加锁层次:所有需要同时加锁互斥量A和互斥量B的代码,必须首先加锁互斥量A,然后加锁互斥量B,即固定加锁顺序。
试加锁和回退:
在锁住某个集合中的第一个互斥量后,使用pthread_mutex_trylock来加锁集合中的其他互斥量,如果失败则将集合中所有已加锁互斥量释放,并重新加锁。

链锁:是层次锁的一个特殊实例,即两个锁的作用范围互相交叠。当锁住第一个互斥量后,代码进入一个区域,该区域需要另一个互斥量。当锁住另一个互斥量后,第一个互斥量就不再需要,可以释放它了。这种技巧在遍历如树型结构或链表结构时十分有用。每一个节点设置一个互斥量,而不是用一个互斥量锁住整个数据结构,阻止任何并行访问。如:遍历代码可以首先锁住队列头或树根节点,找到期望的节点,锁住它,然后释放根节点或队列头互斥量。

windows下互斥量的使用

互斥量: 适用范围:可以跨进程同步,还可以用来保证程序只有一个实例运行(创建命名互斥量),也可以用来做线程间的同步 相关结构:HANDLE hMutex; 相关方法: /* ...
  • s651665496
  • s651665496
  • 2015年07月24日 19:15
  • 1244

c++ 多线程 互斥量

Mutex互斥量也是一个内核对象,用来确保每个线程独占一个资源的访问,
  • qq981932962
  • qq981932962
  • 2014年09月29日 11:52
  • 561

Linux多线程——使用互斥量同步线程

前文再续,书接上一回,在上一篇文章:Linux多线程——使用信号量同步线程中,我们留下了一个如何使用互斥量来进行线程同步的问题,本文将会给出互斥量的详细解说,并用一个互斥量解决上一篇文章中,要使用两个...
  • ljianhui
  • ljianhui
  • 2013年09月02日 00:10
  • 32415

C++11多线程编程之互斥量

C++11多线程编程之互斥量
  • u012333003
  • u012333003
  • 2014年05月07日 15:55
  • 1144

Linux Kernel 互斥量初始化

void __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) { atomic_set(...
  • sunlei0625
  • sunlei0625
  • 2017年03月12日 12:10
  • 408

互斥量属性

转载出处:http://blog.csdn.net/ctthuangcheng/article/details/9357133    互斥量具有一些属性,通过修改这些属性可以控制锁的一些行为。...
  • hbtj_1216
  • hbtj_1216
  • 2016年03月23日 12:02
  • 879

Windows互斥量内核对象

互斥量内核对象用来确保一个线程独占一个资源的访问。 互斥量对象包含了一个使用计数、线程ID以及一个递归计数。互斥量与关键段的行为完全相同,但是互斥量是内核对象,而关键段是用户模式下的同步对象,因此互...
  • luojian5900339
  • luojian5900339
  • 2015年05月28日 16:55
  • 473

浅析线程间通信一:互斥量和条件变量

线程同步的目的简单来讲就是保证数据的一致性。在Linux中,常用的线程同步方法有互斥量( mutex )、读写锁和条件变量,合理使用这三种方法可以保证数据的一致性,本文将讨论互斥量和条件变量的使用,并...
  • MaximusZhou
  • MaximusZhou
  • 2015年01月03日 19:57
  • 2664

Mutex(互斥量)

一、What is Mutex(互斥量)互斥量是用于线程同步的内核对象,用来确保一个线程独占对一个资源的访问.互斥量包含:使用计数 线程ID 递归计数 其中: 线程ID—— 标识当前占用这个互...
  • wangyao1052
  • wangyao1052
  • 2015年04月14日 21:23
  • 1267

嵌入式操作系统内核原理和开发(互斥量)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】       今天下午打开邮箱,打开rawos作者给我发的邮件,甚是惊喜。感谢他对我的支持,因为...
  • feixiaoxing
  • feixiaoxing
  • 2012年09月16日 16:18
  • 5015
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:有关互斥量
举报原因:
原因补充:

(最多只允许输入30个字)