0

我在使用 fork 及其在写入系统上的副本时遇到了一些问题。我将创建 params.writersCount 进程,并且在每个进程中我都需要获取其内部 id(从 1 到 params.writersCount)。所以在孩子中,我正在等待父进程,它初始化孩子的内部 id (writers[i] = processId)。然后我可以调用 writerSimulation 并像参数一样传递上下文地址,因为 context.id 现在是该孩子的正确内部 id,因为在写入系统时复制(context.id = j+1 将强制 unix 复制页面,所以每个孩子然后有自己的上下文副本及其内部 id)。但是如果我尝试在 writerSimulation 函数中使用 context.id,我得到 0。我做错了什么?

for(int i = 0; i < params.writersCount; i++)
{
    pid_t processId = fork();

    if(!processId)
    {   
        srand((unsigned int)(seconds+getpid()));
        while(!context.id)
        {
            for(int j = 0; j < params.writersCount; j++)
            {   
                if(writers[j] == getpid())
                {   
                    context.id = j+1;
                }
            }
            struct timespec wait = {.tv_sec = 0, .tv_nsec = 500000};
            nanosleep(&wait, NULL);
        }
        int simError = writerSimulation(&context);
        return simError;
    }

    writers[i] = processId;
}
4

2 回答 2

0

我并不完全清楚,但看起来你正试图让父母修改孩子中的 writers 数组。那不管用。在分叉之后,父级所做的任何写入都不会在子级中看到,因为写入时复制适用于子级和父级。此外,使用 nanosleep 等待甚至都不可靠。与孩子交流的一种简单方法是在分叉之前打开一个管道,并将其用于同步和传递数据。只需让父级将数据写入管道。孩子在读取时阻塞而不是纳米睡眠,因此同步由读取提供。

于 2012-04-28T16:12:58.780 回答
0

您不能在子级中访问由父级在分叉后分配的值。有几种选择:

  • 改变你的整体方法,这样就不需要了 - 依赖于分叉之前可用的信息,或者在它之后的父母和孩子中独立派生的信息。

  • 使用一种进程间通信方式——套接字、管道、共享内存等

于 2012-04-28T16:17:21.053 回答