我以为我知道c和mutex…显然我没有。
下面的代码,我会打印地址,等待5秒,然后再次打印相同的地址。
它不会-它会打印同一个地址两次,但马上,为什么?是吗?
我用
>gcc -lpthread foobar.c
我一定不明白一些显而易见的事情,这是令人难堪的…
根据jonathan leffler、chris dodd和user3629249的建议,我编辑了下面的代码,同样的问题。这真让人难堪…
美食家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);
}
最佳答案
pthread互斥体用于在单个进程中同步线程。当您调用fork
时,它会创建一个新进程,其中包含所有父进程资源的副本。
因此在本例中,有两个独立的互斥体,一个在父进程中,一个在子进程中。子对象中互斥锁的初始状态是从父对象复制的,但是由于该状态是unlocked,所以这只是一个新的unlocked互斥锁。
然后父对象和子对象都获取自己的互斥量并继续。
如果您将代码更改为调用pthread_create
而不是fork
,那么它的工作方式将更像您(显然)所期望的那样。
注意,可以在不同进程中的线程之间使用pthread互斥——如果在进程共享的共享内存空间中创建互斥,并使用适当的PROCESS_SHARED
属性。
要在共享内存中创建互斥锁,可以将malloc()
调用替换为:
plock = mmap(NULL, (sizeof *plock + 4095) & ~4095UL, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0)
(这里的
4095
值实际上应该比系统页面大小小一个,sysconf(_SC_PAGE_SIZE) - 1
)关于c - 如何获得pthread_mutex_lock()阻止而不是成功?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33336639/