如何让pthread_mutex_lock()阻止而不是成功?

Mar*_*eck 0 c linux pthreads

我以为我认识C和互斥体......显然我没有.

下面的代码,我希望打印地址,等待5秒,然后再次打印相同的地址.

它没有 - 它打印两次相同的地址,但立即,为什么?

我编译代码

>gcc -lpthread foobar.c
Run Code Online (Sandbox Code Playgroud)

我一定不明白一些明显的东西,这是令人尴尬的......

根据Jonathan Leffler和Chris Dodd以及user3629249的建议,我编写了如下代码,同样的问题.这变得非常尴尬......

foob​​ar.c但是:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>


void foobar(pthread_mutex_t *plock) {
    pthread_mutex_lock(plock);
    printf("lock address %p\n", plock);
    fflush(stdout);
    sleep(5);
    pthread_mutex_unlock(plock);
}

int main(void)
{
    pthread_mutex_t *plock;
    pthread_mutexattr_t attr;

    pthread_mutexattr_init(&attr);
    printf("return %d\n", pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED));
    printf("mutex allocated %p\n", plock = malloc(sizeof(pthread_mutex_t)));
    printf("return %d\n", pthread_mutex_init(plock, &attr));
    fork() ? foobar(plock) : foobar(plock);
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*odd 7

pthread互斥体用于在单个进程内同步线程.当您调用时,它会创建一个包含所有父进程资源副本的新进程.fork

所以在这种情况下,有两个独立的互斥体,一个在父进程中,一个在子进程中.子进程中的互斥锁的初始状态是从父进程复制的,但是由于该状态被解锁,所以这只是一个新的解锁互斥锁.

然后父母和孩子都获得自己的互斥量并继续.

如果你要改变你的代码来pthread_create代替fork,那么它会更像你(显然)期待的那样.

请注意,可以在不同进程中的线程之间使用pthread互斥锁 - 如果在进程共享的共享内存空间中创建互斥锁并使用适当的PROCESS_SHARED属性.

要在共享内存中创建互斥锁,您可以使用以下命令替换您的malloc()呼叫:

plock = mmap(NULL, (sizeof *plock + 4095) & ~4095UL, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0)
Run Code Online (Sandbox Code Playgroud)

(4095这里的值应该比系统页面大小小一点,sysconf(_SC_PAGE_SIZE) - 1)