我有以下C函数:
int ipc_test(char *tstr)
{
int *x = mmap(0, 4, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if(fork() == 0) {
*x = getpid();
exit(0);
} else {
int status;
printf("%s: Child %d exited.\n", tstr, wait(&status));
printf("%s: Child pid from mmap: %d\n", tstr, *x);
}
}
我打电话给上面的内容如下:
void *thread_func(void *data)
{
int i=0;
while(i<3) {
ipc_test(data);
i++;
printf("\n");
}
}
int main(int ac, char **av)
{
pthread_t th1, th2, th3;
pthread_create(&th1, NULL, thread_func, "thread1");
pthread_create(&th2, NULL, thread_func, "thread2");
pthread_create(&th3, NULL, thread_func, "thread3");
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_join(th3, NULL);
}
输出:
thread3: Child 13248 exited. thread3: Child pid from mmap: 13248 thread2: Child 13249 exited. thread2: Child pid from mmap: 13249 thread3: Child 13250 exited. thread3: Child pid from mmap: 0 thread3: Child 13252 exited. thread3: Child pid from mmap: 0 thread1: Child 13251 exited. thread1: Child pid from mmap: 13250 thread1: Child 13253 exited. thread1: Child pid from mmap: 0 thread1: Child 13254 exited. thread1: Child pid from mmap: 0 thread2: Child 13255 exited. thread2: Child pid from mmap: 13252 thread2: Child 13256 exited. thread2: Child pid from mmap: 13256
可以注意到打印的pid值存在不匹配。如果我使用互斥锁保护ipc_test
中的代码,则pid值会正确打印。上面使用mmap
函数的方式是不是线程安全的吗?
答案 0 :(得分:2)
虽然您的程序可能存在其他问题,但最明显的问题是您可能会使用wait
等待子进程退出时可能有多个问题。这将随机结束&#34;偷窃&#34;子进程来自另一个线程,而不是等待你想要等待的那个(你刚刚在这个线程中创建的那个)。您需要使用waitpid
并请求您刚刚创建的特定子进程(这需要保存fork
的返回值而不是将其丢弃)。一般来说,除了玩具/示例程序之外,使用wait
基本上总是一个错误。始终将waitpid
与您要等待的显式pid一起使用。