c++ - 在多线程程序中使用管道与子通信

标签 c++ multithreading posix

我正在尝试使用 fork 从多线程父级执行子程序,代码类似于:

#include <thread>
#include <unistd.h>
#include <vector>
#include <sys/wait.h>

void printWithCat(const std::string& data) {
    std::vector<char*> commandLine;
    // exec won't change argument so safe cast
    commandLine.push_back(const_cast<char*>("cat"));
    commandLine.push_back(0);

    int pipes[2];
    pipe(pipes);
    // Race condition here
    pid_t pid = fork();
    if (pid == 0) {
        // Redirect pipes[0] to stdin
        close(pipes[1]);
        close(0);
        dup(pipes[0]);
        close(pipes[0]);
        execvp("cat", &commandLine.front());
    }
    else {
        close(pipes[0]);
        write(pipes[1], (void*)(data.data()), data.size());
        close(pipes[1]);
        waitpid(pid, NULL, 0);
    }

}

int main()
{
     std::thread t1(printWithCat, "Hello, ");
     std::thread t2(printWithCat, "World!");

     t1.join();
     t2.join();
}

此代码包含对 pipe 的调用和对 fork 的调用之间的竞争条件。如果两个线程都创建管道,然后 fork,则每个子进程都包含两个管道的打开文件描述符,并且只关闭一个。结果是管道永远不会关闭,子进程也永远不会退出。我目前将 pipe 和 fork 调用包装在全局锁中,但这增加了额外的同步。有没有更好的办法?

最佳答案

不要以为通过避免代码中的锁定就可以避免同步 - 内核无论如何都会为进程创建获取锁,可能在比你的锁更全局的级别上。

所以继续在这里使用轻量级互斥锁。

当程序的不同部分进行 fork 调用并且不同意单个互斥量(因为有些被埋在库代码中等)时,您的问题就会出现

关于c++ - 在多线程程序中使用管道与子通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19497204/

相关文章:

c - 将 Win32 串行 (RS232) 通信移植到 POSIX

c++ - 对象未声明,void 未在类里面显示

c++ - 在静态库中运行代码,在 main() 之前,当链接器看不到对它的其他引用时

java - 多个单词的 QCompleter 和 QLineEdit

C Unix,pthread_create : fail itself

java - ArrayList 线程安全测试代码失败

c++ - 标记化时强制预处理器评估

java - 当Java LinkedBlocking Queue只有一个元素时,如果同时放入和取出会发生什么?

c - perror 是线程安全的吗?

c - getutent 和 Linux 计时器问题