pthread_mutexattr_setrobust函数用法详解
pthread_mutexattr_setrobust函数简介
- 头文件包含
#include <pthread.h>
- 函数定义
int pthread_mutexattr_getrobust(const pthread_mutexattr_t * attr ,
int * robustness );
int pthread_mutexattr_setrobust(const pthread_mutexattr_t * attr ,
int robustness );
- 编译链接选项
-pthread
pthread_mutexattr_setrobust函数常见使用错误
- 链接错误
undefined reference to `pthread_mutexattr_setrobust'
解决办法:添加链接选项
-pthread
- 编译错误
warning: implicit declaration of function ‘pthread_mutexattr_setrobust’ [-Wimplicit-function-declaration]
解决办法:包含头文件
#include <pthread.h>
pthread_mutexattr_setrobust函数详细描述
pthread_mutexattr_getrobust ()函数将attr引用的互斥属性对象的健壮性属性值放在robustness 中,pthread_mutexattr_setrobust ()函数将attr引用的互斥属性对象的健壮性属性值设置为robustness 中指定的值
robustness属性指定当拥有的线程在没有解锁互斥体的情况下死亡时互斥体的行为。以下值对robustness :有效
- PTHREAD_MUTEX_STALLED这是互斥属性对象的默认值。如果用PTHREAD_MUTEX_STALLED属性初始化互斥体,并且它的所有者没有解锁它就死了,互斥体之后仍然是锁定的,以后任何在互斥体上调用pthread_mutex_lock (3)的尝试都将无限期地阻止。
- PTHREAD_MUTEX_ROBUST 如果使用PTHREAD_MUTEX_ROBUST属性初始化互斥体,并且其所有者在未解锁的情况下死亡,则以后对此互斥体调用pthread_mutex_lock (3)的任何尝试都将成功,并返回 EOWNERDEAD 以指示原始所有者已不存在,互斥体处于不一致状态。通常在 EOWNERDEAD 返回后,下一个拥有者应该在获取的互斥体上调用pthread_mutex_consistent (3),以使其再次一致,然后再使用它。.ip如果下一个所有者在使互斥体保持一致之前使用pthread_mutex_unlock (3)解锁互斥体,则互斥体将永久不可用,并且随后使用pthread_mutex_lock (3)锁定互斥体的任何尝试都将失败,错误为ENOTRECOVERABLE 在这样的互斥体上唯一允许的操作是pthread_mutex_destroy (3)。ip如果下一个所有者在调用pthread_mutex_consistent (3)之前终止,则在此互斥体上进一步的pthread_mutex_lock (3)操作仍将返回EOWNERDEAD
注意,pthread_mutexattr_getrobust ()和pthread_mutexattr_setrobust ()的attr参数应该引用由pthread_mutexattr_init (3)初始化的互斥属性对象,否则行为是未定义的。
pthread_mutexattr_setrobust函数返回值
成功后,这些函数返回0。在出错时,它们返回一个正的错误号。
在glibc实现中,pthread_mutexattr_getrobust ()总是返回零。
pthread_mutexattr_setrobust函数错误码
- EINVAL 将 PTHREAD_MUTEX_STALLED 或 PTHREAD_MUTEX_ROBUST 以外的值传递给pthread_mutexattr_setrobust ()
pthread_mutexattr_setrobust函数其他说明
在Linux实现中,当使用进程共享的健壮互斥体时,如果健壮互斥体的所有者在没有首先解锁互斥体的情况下执行execve (2),等待线程也会收到 EOWNERDEAD 通知。POSIX.1没有指定这个细节,但至少在其他一些实现中也会出现相同的行为。
在向POSIX添加pthread_mutexattr_getrobust ()和pthread_mutexattr_setrobust ()之前,glibc定义了以下等价的非标准函数,如果定义了_GNU_SOURCE:
int pthread_mutexattr_getrobust_np(const pthread_mutexattr_t * attr ,
int * robustness );
int pthread_mutexattr_setrobust_np(const pthread_mutexattr_t * attr ,
int robustness );
相应地,还定义了常数 PTHREAD_MUTEX_STALLED_NP 和 PTHREAD_MUTEX_ROBUST_NP 。
这些特定于GNU的API最初出现在glibc2.4中,现在已经过时,不应该在新程序中使用。
pthread_mutexattr_setrobust函数使用举例
下面的程序演示mutex attributes对象的robustness属性的使用。在这个程序中,一个持有互斥体的线程在没有解锁互斥体的情况下过早死亡。主线程随后成功地获取互斥量,并得到错误EOWNERDEAD ,之后它使互斥量保持一致。
下面的shell会话显示了我们在运行此程序时看到的内容:
$ \fB./a.out\fP
[original owner] Setting lock...
[original owner] Locked. Now exiting without unlocking.
[main] Attempting to lock the robust mutex.
[main] pthread_mutex_lock() returned EOWNERDEAD
[main] Now make the mutex consistent
[main] Mutex is now consistent; unlocking
Program source
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#define handle_error_en(en, msg) \e
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static pthread_mutex_t mtx;
static void *
original_owner_thread(void *ptr)
{
printf("[original owner] Setting lock...\en");
pthread_mutex_lock(&mtx);
printf("[original owner] Locked. Now exiting without unlocking.\en");
pthread_exit(NULL);
}
int
main(int argc, char *argv[])
{
pthread_t thr;
pthread_mutexattr_t attr;
int s;
pthread_mutexattr_init(&attr);
/* initialize the attributes object */
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
/* set robustness */
pthread_mutex_init(&mtx, &attr); /* initialize the mutex */
pthread_create(&thr, NULL, original_owner_thread, NULL);
sleep(2);
/* "original_owner_thread" should have exited by now */
printf("[main] Attempting to lock the robust mutex.\en");
s = pthread_mutex_lock(&mtx);
if (s == EOWNERDEAD) {
printf("[main] pthread_mutex_lock() returned EOWNERDEAD\en");
printf("[main] Now make the mutex consistent\en");
s = pthread_mutex_consistent(&mtx);
if (s != 0)
handle_error_en(s, "pthread_mutex_consistent");
printf("[main] Mutex is now consistent; unlocking\en");
s = pthread_mutex_unlock(&mtx);
if (s != 0)
handle_error_en(s, "pthread_mutex_unlock");
exit(EXIT_SUCCESS);
} else if (s == 0) {
printf("[main] pthread_mutex_lock() unexpectedly succeeded\en");
exit(EXIT_FAILURE);
} else {
printf("[main] pthread_mutex_lock() unexpectedly failed\en");
handle_error_en(s, "pthread_mutex_lock");
}
}
评论区