【问题标题】:C++ : fork/exec or pthread?C++:fork/exec 还是 pthread?
【发布时间】:2012-07-19 07:53:57
【问题描述】:

我正在编写一个程序,一旦按下按钮,我必须执行一个服务器进程(只有在我决定杀死他时才会停止)。
为了执行这个过程,我决定使用 fork/execv 机制:

void Command::RunServer() {

    pid = fork();

    if (pid==0) {
        chdir("./bin");
        char str[10];
        sprintf(str,"%d",port);
        char *argv[] = {"./Server", str};
        execv("./Server",argv);
    }
    else {
        config->pid = pid;
        return;
    }
}

在“按钮按下”的方法中,我这样做:

command->RunServer();

几天前它似乎工作得很好......现在我得到了错误:

main: xcb_io.c:221: poll_for_event: Assertion `(((long) (event_sequence) - (long) (dpy->request)) <= 0)' failed.

我应该尝试切换到 pthread 吗?我做了什么坏事吗?

谢谢,
呵呵

【问题讨论】:

  • char *argv[] = {"./Server", str, NULL};
  • 哦,是的,抱歉,它改变了一些东西。 ps 中的进程描述现在很干净,以前很丑,有很多 args。

标签: c++ pthreads exec fork


【解决方案1】:

当您执行fork() 时,您进程的所有文件描述符都将复制到新的文件描述符中。当您执行exec*() 时,所有文件描述符也会被保留,除非它们被标记为FD_CLOEXEC

我的猜测是某些库(可能是 Xlib)使用的某些 fd 被新进程继承,并且重复导致程序混乱。

在这些情况下,如果您想保持标准 I/O 处于打开状态,则 BSD 函数 closefrom() (closefrom(3)) 很有用。不幸的是,在 linux 中没有这样的功能,所以你必须做一个封闭的循环或类似的事情:

int open_max = sysconf (_SC_OPEN_MAX);
for (int i = 3; i < open_max; i++)
    close(i);

您可以阅读有关此问题的更多信息here

【讨论】:

  • Nice :) 似乎有效.. 为什么它从 3 开始?前两个是具体的吗?
  • 标准输入、标准输出、标准错误。前三个是特殊的。
【解决方案2】:

在对execv 的调用中,argv 必须以空指针终止。 前一行应该是:

char* argv[] = { "./Server", str, NULL };

【讨论】:

  • 是的,谢谢我注意到这一点,当它不是以 NULL 指针结尾时,我的进程名称非常难看,带有未编码的字符。现在效果很好。
猜你喜欢
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
  • 2013-05-06
  • 2015-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多