【问题标题】:Fork child and parent running separate code分叉子和父运行单独的代码
【发布时间】:2012-03-29 01:48:50
【问题描述】:

我正在尝试对两个向量进行点积,每个进程都有一个单独的开始和结束索引。似乎正在发生的事情是代码被执行了两次。

void DotProduct::MultiProcessDot()
    {
    pid_t pID,w;
    int status;   
    unsigned int index = mNumberOfValuesPerVector / 2;

    if((pID = fork()) < 0){
        cout << "fork error" << endl;
    }
    else if(pID == 0){ /* child */
        ProcessDotOperation(0, index);
        exit(EXIT_FAILURE);
    }
    else{ /* parent */
        ProcessDotOperation(index, mNumberOfValuesPerVector);
        w = waitpid(pID, &status, WNOHANG);
        if(w == 0){
            cout << "alive" << endl;
        }else if(w == -1){
            cout << "dead" << endl;
        }
    }
}

ProcessDotOperation 使用与sem_wait()sem_post() 的共享内存计算点积。似乎正在发生的事情是这样的:

  • 父运行ProcessDotOperation

  • “活着”被打印出来

  • 父运行ProcessDotOperation

  • “活着”被打印出来

  • 程序继续执行(继续执行其他功能)

  • 孩子跑ProcessDotOperation

  • 孩子跑ProcessDotOperation

注意:我可能对正在发生的事情有一个根本性的误解,所以 parentchild 指的是代码中的 cmets,即我认为正在运行的进程。

如何让子进程运行一次ProcessDotOperation,父进程运行一次ProcessDotOperation,然后程序继续运行?

感谢任何帮助。

编辑

如果我在fork() 之前打印,并将w = waitpid(pID, &amp;status, WNOHANG); 更改为w = waitpid(pID, &amp;status, 0);,输出如下:

分叉

父母

孩子

分叉

父母

孩子

继续执行...

这是ProcessDotOperation的代码:

void DotProduct::ProcessDotOperation(unsigned int startIndex, unsigned int endIndex)
{

    for(unsigned int i = startIndex; i < endIndex; i++){
        sem_wait(mSem);

        mShmProductId += mVectors[0][i] * mVectors[1][i];
        cout << startIndex << " " << endIndex << " " << i << endl;

        sem_post(mSem);
    }
}

【问题讨论】:

  • 您对fork() 工作原理的理解是完全正确的。你显示的代码应该做你想做的事。您需要在调试方面提升您的游戏水平。尝试在调用 fork() 之前打印一行。尝试从ProcessDotOperation 内部打印getpid() 的参数和值。尝试在调用wait() 之前打印pID 的值。
  • ProcessDotOperation 的代码是什么?
  • Aside:考虑使用std::thread 而不是fork() 和共享内存。
  • 尝试在 ProcessDotOperation 中添加一个调试 printf,包括调用者的 PID。
  • @Rob,我猜他的作业做不到 :)

标签: c++ fork shared-memory


【解决方案1】:

有人第二次调用 MultiProcessDot。

【讨论】:

    【解决方案2】:

    我认为您需要围绕waitpid() 进行循环。正如它所写的那样,您等待一次,而不是等待死去的孩子,如果孩子还没有死,就立即返回。当然,这允许父母继续进行其他活动。

    我不确定这是对您观察到的内容的完整解释,但我们看不到您的跟踪代码。在每条消息中打印进程的 PID 等内容。

    【讨论】:

      猜你喜欢
      • 2021-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 2019-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多