PTHREAD_MUTEXATTR_SETROBUST - Linux手册页

时间:2019-08-20 18:01:04  来源:igfitidea点击:

Linux程序员手册 第3部分
更新日期: 2020-06-09

名称

pthread_mutexattr_getrobust,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。

glibc的功能测试宏要求(请参阅feature_test_macros(7)):

pthread_mutexattr_getrobust(),pthread_mutexattr_setrobust():

_POSIX_C_SOURCE>= 200809L

说明

pthread_mutexattr_getrobust()函数将attr引用的互斥量属性对象的稳健性属性的值放在* robustness中。 pthread_mutexattr_setrobust()函数将attr引用的互斥体对象的稳健性属性值设置为* 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)以使其再次保持一致,然后再使用它。
如果下一个所有者在使其一致之前使用pthread_mutex_unlock(3)解锁互斥锁,则该互斥锁将永久不可用,并且随后使用pthread_mutex_lock(3)对其进行锁定的任何尝试均将失败,并显示错误ENOTRECOVERABLE。在这种互斥锁上唯一允许的操作是pthread_mutex_destroy(3)。
如果下一个所有者在调用pthread_mutex_consistent(3)之前终止,则对该互斥锁的进一步pthread_mutex_lock(3)操作仍将返回EOWNERDEAD。

请注意,pthread_mutexattr_getrobust()和pthread_mutexattr_setrobust()的attr参数应引用由pthread_mutexattr_init(3)初始化的互斥属性对象,否则该行为是不确定的。

返回值

成功时,这些函数返回0。错误时,它们返回正错误号。

在glibc实现中,pthread_mutexattr_getrobust()始终返回零。

错误说明

EINVAL
除了PTHREAD_MUTEX_STALLED或PTHREAD_MUTEX_ROBUST之外的其他值都已传递给pthread_mutexattr_setrobust()。

版本

在版本2.12中将pthread_mutexattr_getrobust()和pthread_mutexattr_setrobust()添加到了glibc。

遵循规范

POSIX.1-2008。

备注

在Linux实现中,当使用进程共享的健壮互斥锁时,如果健壮互斥锁的所有者执行execve(2)而不先解锁互斥锁,则等待线程还会收到EOWNERDEAD通知。 POSIX.1未指定此详细信息,但至少在其他一些实现中也发生相同的行为。

在将POSIX添加pthread_mutexattr_getrobust()和pthread_mutexattr_setrobust()之前,如果定义了_GNU_SOURCE,则glibc定义了以下等效的非标准函数:

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最初出现在glibc 2.4中,如今已过时,不应在新程序中使用。

示例

下面的程序演示了互斥量属性对象的稳健性属性的用法。在此程序中,持有互斥锁的线程会过早死掉而不会解锁互斥锁。主线程随后成功获取该互斥锁,并得到错误EOWNERDEAD,此后使该互斥锁保持一致。

以下shell会话显示了我们在运行该程序时看到的内容:

$ ./a.out
[original owner] Setting lock...
[original owner] Locked. Now exiting without unlocking.
[main thread] Attempting to lock the robust mutex.
[main thread] pthread_mutex_lock() returned EOWNERDEAD
[main thread] Now make the mutex consistent
[main thread] 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) \
               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...\n");
    pthread_mutex_lock(&mtx);
    printf("[original owner] Locked. Now exiting without unlocking.\n");
    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 thread] Attempting to lock the robust mutex.\n");
    s = pthread_mutex_lock(&mtx);
    if (s == EOWNERDEAD) {
        printf("[main thread] pthread_mutex_lock() returned EOWNERDEAD\n");
        printf("[main thread] Now make the mutex consistent\n");
        s = pthread_mutex_consistent(&mtx);
        if (s != 0)
            handle_error_en(s, "pthread_mutex_consistent");
        printf("[main thread] Mutex is now consistent; unlocking\n");
        s = pthread_mutex_unlock(&mtx);
        if (s != 0)
            handle_error_en(s, "pthread_mutex_unlock");

        exit(EXIT_SUCCESS);
    } else if (s == 0) {
        printf("[main thread] pthread_mutex_lock() unexpectedly succeeded\n");
        exit(EXIT_FAILURE);
    } else {
        printf("[main thread] pthread_mutex_lock() unexpectedly failed\n");
        handle_error_en(s, "pthread_mutex_lock");
    }
}

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/