我以为我认识C和互斥体......显然我没有.
下面的代码,我希望打印地址,等待5秒,然后再次打印相同的地址.
它没有 - 它打印两次相同的地址,但立即,为什么?
我编译代码
>gcc -lpthread foobar.c
Run Code Online (Sandbox Code Playgroud)
我一定不明白一些明显的东西,这是令人尴尬的......
根据Jonathan Leffler和Chris Dodd以及user3629249的建议,我编写了如下代码,同样的问题.这变得非常尴尬......
foobar.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)
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)