加载中…
个人资料
liufeifei11
liufeifei11
  • 博客等级:
  • 博客积分:0
  • 博客访问:46,434
  • 关注人气:5
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
正文 字体大小:

[转载]PTHREAD_MUTEX(3)

(2012-05-08 17:44:18)
标签:

转载

分类: linux程序
很不错~
原文地址:PTHREAD_MUTEX(3)作者:YinFeeling
PTHREAD_MUTEX(3)

名称
 pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock,
 pthread_mutex_unlock, pthread_mutex_destroy – 互斥体操作

大纲
 #include
 pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

描述
 mutex是一种互斥体设备,在并发,实现临界和监控时对保护数据很有帮助。
互斥体有两种可能的状态:未锁定(不被任何线程拥有)和锁定(被一个线程拥有)。一个互斥体在任何情况下都不可能被两个线程同时拥有。当一个线程试图去锁定一个已经被其它线程锁定的互斥体时,它会一直等待直到拥有锁的线程先解除锁定。

 pthread_mutex_init函数依据mutexattr指定的属性初始化mutex指向的互斥设备。如果mutexattr为NULL,使用默认属性。
 LinuxThread只实现了一种互斥属性:mutex类型,值为’fast’,’recursive’或’error checking’之一。mutex类型取决于拥有它的线程能否将它再锁定一次。默认的类型是’fast’。关于mutex的属性请查看pthread_mutexattr_init(3)获取更多的信息。

 pthread_mutex_t变量可以静态的进行初始化,使用PTHREAD_MUTEX_INITIALIZER(fast mutex),或PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP( recursive mutex), 或PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP(error checking mutex)。

 pthread_mutex_lock函数锁定给定的互斥体。如果互斥体当前是未锁定状态,锁定它并且会属于调用线程,然后立刻返回。如果互斥体已经被其它线程锁定,调用线程将被挂起,直到互斥体被释放。
如果互斥体已经被调用者锁定,pthread_mutex_lock函数的行为取决于互斥体的类型。如果互斥体的类型是fast,调用线程将被挂起直到互斥体被释放,这会引起调用线程的死锁。如果互斥体的类型是’error checking’,pthread_mutex_lock立即返回EDEAKLK。如果互斥体是recursive类型的,pthread_mutex_lock会调用成功,并立即返回,它将记录下调用者锁定互斥体的次数。要释放互斥体也必须调用相同次数的pthread_mutex_unlock函数。

 pthread_mutex_trylock函数的行为和pthread_mutex_lock几乎一样,只是如果互斥体已经锁定,它不会挂起调用线程,而是立即返回一个EBUSY的出错码。

 pthread_mutex_unlock释放一次指定的互斥体。它假设给定的互斥体是锁定的,并且被调用者拥有。如果是fast类型的互斥体,pthread_mutex_unlock会将互斥体置为未锁定状态,如果是recursive类型,会在锁定的次数上减一,只有这个数为0时,互斥体才真正的被释放。

对于error checking类型的互斥体,pthread_mutex_unlock只在运行时检查是否是当前线程拥有互斥体,以及是不是当前线程在调用pthread_mutex_unlock函数。如果不是这些情况的一种,互斥体的状态不会改变,会返回一个出错码。’fast’和’recursive’不执行这样的检查,因此也就允许另一个线程释放这个线程的锁定。这不是可移植的行为,因此也不可靠。

 pthread_mutex_destroy销毁一个互斥体,释放它可能持有的资源。此时的互斥体必须是未锁定的。在LinuxThread的实现当中,互斥体不占用任何资源,因此pthread_mutex_destroy除了检查互斥体是否处于锁定状态外也没作什么。

取消
没有任何一个互斥体函数是取消点,甚至是pthread_mutex_lock也不行,不管它可能会被挂起多长时间。这样,取消点的状态就是可预见的,就允许线程在停止执行之前来释放一个需要被释放的互斥体。因此,使用延时取消的线程永远不要在互斥体中使用延时操作。

同步信号的安全性
互斥体函数对同步信号是不安全的。这句话的意思是说,它们不应该被信号处理函数调用。特别的,如果它们被信号处理函数调用可能会导致死锁。

返回值
 pthread_mutex_init函数总是返回0.其它的函数在调用成功的时候返回0,出错的时候返回非零的出错码。

出错码
 pthread_mutex_lock函数在出错时返回下面的代码:
 EINVAL:互斥体没有被正确的进行初始化。
 EDEAKLK:互斥体已经被调用者锁定。(仅针对error checking类型。)

 pthread_mutex_trylock函数在出错时返回下面的代码:
 EBUSY:互斥体不能使用,因为它已经被锁定。
 EINVAL:未被正确初始化。

 pthread_mutex_unlock函数在出错时返回下面的代码:
 EINVAL:未被正确初始化。
 EPERM:调用者不拥有互斥体(只针对error checking类型)。

 pthread_mutex_destroy函数在出错时返回下面的代码:
 EBUSY:互斥体已经被锁定。

作者
 Xavier Leroy

参见
 pthread_mutexattr_init(3), pthread_mutexattr_setkind_np(3),
 pthread_cancel(3).

示例:
全局共享变量可以像下面一样使用互斥体保护起来:
 int x;
 pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
所有访问和修改x的操作都应该用pthread_mutex_lock和pthread_mutex_unlock包装起来:
pthread_mutex_lock(&mut);

 pthread_mutex_unlock(&mut);


0

  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有