【问题标题】:mmap() for shared memory and threadsmmap() 用于共享内存和线程
【发布时间】:2014-10-01 12:26:55
【问题描述】:

我有以下 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);
}

输出:

线程 3:子 13248 已退出。 thread3:来自 mmap 的子 pid:13248 线程 2:子 13249 已退出。 thread2:来自 mmap 的子 pid:13249 线程 3:子 13250 已退出。 thread3:来自 mmap 的子 pid:0 线程 3:子 13252 已退出。 thread3:来自 mmap 的子 pid:0 线程 1:子 13251 已退出。 thread1:来自 mmap 的子 pid:13250 线程 1:子 13253 已退出。 thread1:来自 mmap 的子 pid:0 thread1:子 13254 已退出。 thread1:来自 mmap 的子 pid:0 线程 2:子 13255 已退出。 thread2:来自 mmap 的子 pid:13252 线程 2:子 13256 已退出。 thread2:来自 mmap 的子 pid:13256

可以注意到打印的 pid 值不匹配。如果我用互斥锁保护ipc_test 中的代码,pid 值会正确打印。上面mmap函数的使用方式不是线程安全的吗?

【问题讨论】:

    标签: c multithreading pthreads ipc mmap


    【解决方案1】:

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

    【讨论】:

    • 感谢您指出这一点。我将替换它。您还发现了哪些其他问题?
    • 使用waitpid后,输出是有序的,没有使用互斥体。
    • 没有立即解决,但我只是想明确一点,我的回答是报告一个问题,我不确定是否还有其他问题。
    猜你喜欢
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 2014-02-14
    • 2018-05-07
    • 2021-05-16
    • 2016-06-25
    • 2012-07-29
    相关资源
    最近更新 更多