【问题标题】:mutex attribute PTHREAD_PROCESS_SHARED inverts logic?互斥属性 PTHREAD_PROCESS_SHARED 反转逻辑?
【发布时间】:2013-07-23 11:42:49
【问题描述】:

这是我之前的问题 (pthread mutex (un)locking over different threads) 的后续问题。我对如何处理这里的问题和答案感到困惑,所以我重新尝试一下:o)

我正在尝试通过进程和线程处理互斥锁,并使用互斥锁属性 PTHREAD_PROCESS_SHARED 来安排它。我添加了一个小示例(基于我之前帖子中 Paolo 的示例),它展示了我的问题:

#include <stddef.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <semaphore.h>

pthread_mutex_t m;
sem_t s1, s2;

void print(const char *s, int err)
{
    printf("%s %d %s\n", s, err, strerror(err));
}

void *start_t1(void *arg)
{
    sem_wait(&s1); // <-t2
    print("t1: unlock ", pthread_mutex_unlock(&m));
    sem_post(&s2); //->t2
}

void *start_t2(void *arg)
{
    sem_wait(&s2); // <-main
    print("t2: lock ", pthread_mutex_lock(&m));
    sem_post(&s1); // ->t1

    sem_wait(&s2); // <-t1
    sem_post(&s1); // ->main
}

void main(void)
{
    pthread_mutexattr_t mattr;
    pthread_mutexattr_init(&mattr);
    pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_ERRORCHECK_NP);
    pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);

    sem_init(&s1, 0, 0);
    sem_init(&s2, 0, 0);

    print("main init", pthread_mutex_init(&m, &mattr));

    pthread_t t2, t1;
    pthread_create(&t1, NULL, start_t1, NULL);
    pthread_create(&t2, NULL, start_t2, NULL);

    sem_post(&s2); // ->t2
    sem_wait(&s1); // <-t2

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
}

输出是:

main init 0 Success
t2: lock  0 Success
t1: unlock  1 Operation not permitted

不允许 T1 解锁在 main 中初始化并由 T2 锁定的互斥锁。这不是我所期望的!由于类型 PTHREAD_PROCESS_SHARED,应该允许 T1 解锁互斥锁。我错了吗?

如果将互斥体初始化更改为使用默认属性 (pthread_mutex_init(&amp;m, **NULL**)),则它可以正常工作。

main init 0 Success
t2: lock  0 Success
t1: unlock  0 Success

似乎是某种倒置的逻辑!

【问题讨论】:

    标签: attributes pthreads mutex shared


    【解决方案1】:

    绝不允许线程解锁它没有锁定的 pthreads 互斥锁。对于错误检查互斥体的情况,在这种情况下会返回错误;在默认和普通互斥体的情况下,行为是未定义的。

    PTHREAD_PROCESS_SHARED的目的是为了让互斥锁可以用来同步不同进程中的线程。

    【讨论】:

    • 那么,“允许...同步不同进程中的线程”和“通过同一进程中的不同线程锁定/解锁”有什么区别我>”?我的意思是,从技术上讲。这是否意味着,由线程 P1T1 锁定的共享互斥锁 M1 将阻塞线程 P2T1 ,除非 P1T1 将解锁 M1 ?谁是所有者?
    • 是的,就是这个意思。锁定互斥锁的线程是所有者;在这种情况下,P1T1 是所有者。互斥体允许线程之间的互斥:在非进程共享互斥体的情况下,这些线程必须都是同一进程的一部分,互斥体才能按指定操作;在进程共享互斥体的情况下,这些线程被允许成为不同进程的一部分。
    • 谢谢,我想现在更清楚了。回到我原来的例子:默认属性互斥锁的 t1 的“成功”只是偶然的,尽管尚未确定,根据 man pthread_mutex_unlock。
    • @Mladen:对。 “未定义”的一种可能表现形式是它按您预期的方式工作(或至少看起来如此)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多