Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在子调用exec()之后使用管道()_C_Pipe_Exec_Parent Child_Ipc - Fatal编程技术网

在子调用exec()之后使用管道()

在子调用exec()之后使用管道(),c,pipe,exec,parent-child,ipc,C,Pipe,Exec,Parent Child,Ipc,我的最终目标是让父进程将文本行传递给子进程,然后子进程将文本打印到标准输出。孩子将在后台“永久”运行,而家长获得用户输入并将其传递给孩子。我更喜欢孩子单独参加一个节目。通过if语句来区分child和paretn就像是胡说八道 我正在研究管道,但我不确定在父/子系统调用了另一个程序的exec()之后,管道是否可能在父/子系统之间进行通信 这可能吗?如果是的话,你能给我举个例子吗?如果没有,在这种情况下我可以使用什么样的IPC方法?标准场景是让程序作为子级执行,不知道管道,只使用stdin/stdo

我的最终目标是让父进程将文本行传递给子进程,然后子进程将文本打印到标准输出。孩子将在后台“永久”运行,而家长获得用户输入并将其传递给孩子。我更喜欢孩子单独参加一个节目。通过if语句来区分child和paretn就像是胡说八道

我正在研究管道,但我不确定在父/子系统调用了另一个程序的
exec()
之后,管道是否可能在父/子系统之间进行通信


这可能吗?如果是的话,你能给我举个例子吗?如果没有,在这种情况下我可以使用什么样的IPC方法?

标准场景是让程序作为子级执行,不知道管道,只使用
stdin
/
stdout
。通过将管道的相应端作为fd
0
1
(或两个管道都用于双向通信),对应于
STDIN\u FILENO
STDOUT\u FILENO
,可以实现这一点。在此之后,执行您的子程序

当然,如果您需要
stdin
/
stdout
以在孩子身上实现不同的目的,也有类似于“命名管道”的替代方案

但是,如果您自己编写这两部分,您可能需要考虑更简单的解决方案:

通过if语句来区分孩子和家长就像胡扯一样杂乱无章

无论如何,您必须这样做,至少在连接管道和调用exec()时是这样。只需创建单独的代码文件,并根据需要调用
parent_main()
child_main()

在exec*()函数之后,子进程共享父进程的所有文件描述符。因此,如果在fork()之前创建一个管道,则可以在这两个管道中读取/写入fd

通常的方法是:

  • 创建管道(读fd、写fd)
  • fork()
  • 在父项中:
    • 关闭读取fd(此处不从父级读取)
    • 将数据写入写入fd
    • 等待/死亡
  • 儿童:
    • 关闭写入fd(您不会从子级写入)
    • 从读取fd读取数据
    • 等待/死亡

看不出为什么要执行新流程。如果真的需要,您必须使用标准stdin/stdout(请参阅其他答案),或者有一个程序将接受fd(filedescriptor,整数)作为参数,以便知道哪个是管道。对我来说似乎不是很好。

事实上,通过自动管理通信通道,这样做容易得多

FILE*popen(const char*命令,const char*模式)
函数应执行字符串指定的命令
指挥部。它应在调用程序和
已执行的命令,并应返回指向可执行的流的指针
用于读取或写入管道

执行命令的环境应与子进程一样 使用fork()函数在popen()调用中创建,以及 子级使用以下调用调用sh实用程序:

execl(shell路径,“sh”,“-c”,命令,(char*)0)

其中,shell path是sh实用程序的未指定路径名

popen()函数应确保来自上一个 在父进程中保持打开状态的popen()调用在 新的子进程

popen()的mode参数是一个指定I/O模式的字符串:

如果模式为r,则启动子进程时,其文件描述符 STDOUT_FILENO应为管道的可写端,文件 调用进程中的描述符fileno(stream),其中stream是 popen()返回的流指针应为 烟斗

如果mode为w,则启动子进程时,其文件描述符 标准DIN_文件号应为管道的可读端,且文件 调用进程中的描述符fileno(stream),其中stream是 popen()返回的流指针应为 烟斗

如果mode是任何其他值,则结果未定义

在popen()之后,父进程和子进程都应能够 在任何一方终止之前独立执行

管道流是面向字节的

返回值

成功完成后,popen()将返回指向打开的 可用于读取或写入管道的流。否则, 应返回空指针,并可设置errno以指示错误

例如,假设您要向孩子发送
Hello world

#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
int main()
{
  FILE* toChild;
  toChild = popen("./child", "w");//child is executable of the other file: change the name
  int res = fputs( "Hello World\n", toChild);
  pclose(toChild);
  return 0;
}
int main()
{
  char p[100];
  int n;
  do{
    n = scanf("%s", p);
    if (n>0) {
    printf("INPUT MESSAGE: \"%s\n\"", p);
    //free(p);
    }
    else {
      printf( "%d, No matching characters\n", n);
    }
  }while(n>0);
  return 0;
}

如果您使用的是纯POSIX系统(而不是OSX),您还可以使用
scanf(“%ms”,&p)
char*p
,然后使用
free(p)

我想我是跳枪了,很乐意删除我的评论,这会让@amon看起来很奇怪。很高兴看到你得到了答案。@amon-我正在删除我的评论(见上面的评论)谢谢kevin。别担心。我也会移除我的。谢谢,你的回答正是我所需要的。非常感谢。我喜欢你简化亲子关系的方式,让它看起来不像我原来认为的那样凌乱。