【问题标题】:how to send a string from child to parent using pipe如何使用管道将字符串从孩子发送到父母
【发布时间】:2019-03-23 21:45:30
【问题描述】:

我正在尝试将字符串从parent[0] 发送到child[1]。字符串的大小是固定的,所以每次长度都可以不同。

父母:

std::string x;
while(read(fd[WRITE_FD], &x, x.length()) > 0)
    {
      cout<< x;
    }

【问题讨论】:

  • 请检查readwrite函数的参数类型。
  • read(fd[WRITE_FD], &amp;x, x.length()); 你不能用字符串做到这一点,
  • read(fd[WRITE_FD], &amp;x, x.length()); 如果第二个参数有效,x.length() 仍然是 0。

标签: c++ string pipe


【解决方案1】:

std::string 不适合作为read 的第二个参数。您需要传递 read 一个缓冲区,将其数据连同要从管道读取的字节数一起写入该缓冲区。

如果您先将字符串的长度写入管道,您的生活会变得更加简单。这样你就可以知道要从管道中读取多少字节:

int main() {
    int fd[2];
    pipe(fd);

    pid_t pid = fork();
    if (pid == 0) {
        close(fd[0]);
        std::string str = "some data";
        std::string::size_type size = str.size();
        write(fd[1], &size, sizeof(size));
        write(fd[1], str.c_str(), str.size());
    } else {
        close(fd[1]);
        std::string::size_type size;
        read(fd[0], &size, sizeof(size));
        std::string str(size, ' ');
        // This depends on the fact that the pointer returned by data
        // is non-const in C++17.
        // Use &str[0] instead of str.data() if using an older C++ standard
        read(fd[0], str.data(), size);
    }
}

在此示例中,子进程首先将字符串的长度写入管道,然后将字符串数据本身写入(值得注意的是,它不会将 nul 终止符写入管道)。然后父级读取长度,分配适当大小的字符串,并将数据读入由该字符串管理的缓冲区。


如果您不想先写入字符串的长度,则必须一次读取一个块,直到找到一个以 nul 字节结尾的块:

int main() {
    int fd[2];
    pipe(fd);

    pid_t pid = fork();
    if (pid == 0) {
        close(fd[0]);
        std::string str = "some data";
        write(fd[1], str.c_str(), str.size() + 1);
    } else {
        close(fd[1]);
        std::string str;
        while (true) {
            char c[100];
            ssize_t count = read(fd[0], c, 100);
            if (c[count - 1] == '\0') {
                // Don't copy an extra nul terminator into the string object
                str.append(c, c + count - 1);
                break;
            } else {
                str.append(c, c + count);
            }
        }
    }
}

在此示例中,子进程将字符串数据写入带有 nul 终止符的管道。然后父进程从管道中读取 100 字节的块,将数据附加到字符串中,直到它读取一个以 nul 字节结尾的块。

【讨论】:

  • 除了read(fd[WRITE_FD], str.data(), size);之外,一切都很好
  • @ItayGoldfaden 您是否阅读了该行上方的评论?如果您不使用 C++17,则需要使用 &amp;str[0],因为 std::string::data 返回 const char*。如果这不是问题,您需要更具体地说明您所看到的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-15
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多