Reputation: 157
I am having the following C function:
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);
}
}
I am calling the above as below:
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);
}
Output:
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
It can be noticed that there are mismatches in the pid values printed. If I guard the code in ipc_test
with a mutex, the pid values get printed properly. Is the way the mmap
function is used above not thread safe?
Upvotes: 2
Views: 2100
Reputation: 215193
While there may be other problems in your program, the most obvious problem is that you're using wait
to wait for a child process to exit when there may be more than one. This will end up randomly "stealing" the child process from another thread rather than waiting for the one you wanted to wait for (the one you just created in this thread). You need to use waitpid
and request the specific child process you just created (which requires saving the return value of fork
rather than throwing it away). In general, use of wait
is essentially always a bug except in toy/sample programs. Always use waitpid
with the explicit pid you want to wait for.
Upvotes: 2