【问题标题】:Forks and PIDs in CC 中的分叉和 PID
【发布时间】:2015-10-30 20:15:42
【问题描述】:

我在这个 C 练习中发现了一些困难:我被要求创建一个服务器套接字,它(通过无限循环)从输入流中读取一个字符串。如果字符串读取“self”,则服务器在输出流上打印服务器自己的 pid。如果它读取“fork”,它会调用 fork() 函数并打印孩子的 pid。 我正在考虑将这些行包含在 while 循环中

if (strcmp(val,"self")==0) sprintf(result,"%d\n",getpid());
else if (strcmp(val,"fork")==0){
    pid = fork();
    if (pid == 0) sprintf(result, "%d\n", getpid());

我测试了它,当我只写一次“self”或“fork”时,它实际上工作正常。如果我多次尝试发出“fork”命令,它就会“卡住”,这意味着我必须重复该命令两到三遍才能真正获得所需的结果。

这是我做的一个例子(我使用 telnet 来测试服务器):

 Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
self
4313
fork
4324
fork
fork
self
4313
fork
fork
fork 
4327
fork
fork 
fork
4328

有什么想法吗?

【问题讨论】:

  • 我们需要查看fork 代码的其余部分。为什么要输出在孩子身上?孩子输出后做什么?
  • 请提供SSCCE:sscce.org

标签: c sockets fork pid child-process


【解决方案1】:

分叉后,您需要管理孩子。 fork 后要做的第一件事就是检查你是父进程还是子进程,然后根据你所在的位置做不同的事情。

在孩子身上:

  • 做任何你需要做的事,然后退出。根据您的描述,孩子可能不需要做任何事情,在这种情况下它可以立即退出。

    如果您不退出,那么孩子将继续做与父母相同的事情。它会踩到父级的脚趾,读取父级的输入并弄乱其输出并造成其他类型的小破坏。

    建议使用_Exit() 退出子进程,而不是exit()exit() 将运行清理代码,例如刷新您真正只希望父级运行的 stdio 缓冲区。

在父级中:

  • 获取孩子的 PID 并打印出来。
  • 等待孩子退出wait()

    孩子应该立即退出,所以等待不应该长时间阻塞。等待子进程确保子进程被清理并且不会变成zombie process

【讨论】:

  • 可以直接SIG_IGNSIGCHLD,而不是wait()
猜你喜欢
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-25
  • 2010-12-14
  • 1970-01-01
  • 2013-11-18
相关资源
最近更新 更多