mmap()用于共享内存和线程

时间:2014-08-08 05:17:23

标签: c multithreading pthreads ipc mmap

我有以下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函数的方式是不是线程安全的吗?

1 个答案:

答案 0 :(得分:2)

虽然您的程序可能存在其他问题,但最明显的问题是您可能会使用wait等待子进程退出时可能有多个问题。这将随机结束&#34;偷窃&#34;子进程来自另一个线程,而不是等待你想要等待的那个(你刚刚在这个线程中创建的那个)。您需要使用waitpid并请求您刚刚创建的特定子进程(这需要保存fork的返回值而不是将其丢弃)。一般来说,除了玩具/示例程序之外,使用wait基本上总是一个错误。始终将waitpid与您要等待的显式pid一起使用。