用C++创建rw管道的最佳方式是什么?
我有需要将命令发送到节目B的stdin和读回该程序B的输出的程序的(在C++编程,不仅LINUX)用C++创建rw管道的最佳方式是什么?
ProgramA - >发送字母A - >程序B 程序A < - B的输出< - 程序B
我实际上有第一部分,发送命令给B,使用popen()。我知道popen只是一种方式。
那么,使用C++进行双向的最佳方式是什么?
使用posix功能(所以,将在linux和任何符合posix标准的系统上工作),您可以使用pipe/execl/dup的组合。总之什么情况是:
- 创建2个管道(一个读和一个写孩子)
- 叉当前进程。这保持打开关闭当前stdin/stdout相同的fd
- 。然后使用DUP(它使用的最低可用描述符重复你给它)
- execl的子进程
讲究,需要一些刷新。 父的代码是:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int pipe_in[2]; /* This is the pipe with wich we write to the child process. */
int pipe_out[2]; /* This is the pipe with wich we read from the child process. */
if (pipe (pipe_in) || pipe (pipe_out)) {
fprintf (stderr, "Error in creating pipes!\n");
exit (1);
}
/* Attempt to fork and check for errors */
if ((pid = fork()) == -1) {
fprintf (stderr, "Error in fork!\n");
exit (1);
}
if (pid) {
/* The parent has the non-zero PID. */
char temp[100];
int result;
FILE* child_in;
FILE* child_out;
child_in = fdopen(pipe_out[0],"r");
child_out = fdopen(pipe_in[1],"w");
close(pipe_out[1]);
close(pipe_in[0]);
fprintf(child_out, "something\n");
fgets(temp,100,child_in);
printf(" Read from child %s \n", temp);
/* Send a command to the child. */
fprintf(child_out, "quit\n");
fflush(child_out);
fgets(temp,100,child_in);
printf(" Read from child %s \n", temp);
wait (&result); /* Wait for child to finish */
}
else {
/* The child has the zero pid returned by fork*/
close (1);
dup (pipe_out[1]); /* dup uses the lowest numbered unused file descriptor as new descriptor. In our case this now is 1. */
close (0); /* dup uses the lowest numbered unused file descriptor as new descriptor. In our case this now is 0. */
dup (pipe_in[0]);
close (pipe_out[0]);
close (pipe_out[1]);
close (pipe_in[0]);
close (pipe_in[1]);
execl ("child", "child", NULL);
exit(1); /* Only reached if execl() failed */
}
return 0;
}
一个简单的孩子是:
#include <stdio.h>
#include <string.h>
int main()
{
char temp[100];
do {
printf ("In child: \n");
fflush (stdout);
fgets (temp, 100, stdin);
printf ("Child read %s\n", temp);
fflush (stdout);
} while (!strstr (temp, "quit"));
return 0;
}
您可以编译他们:
gcc -o parent parent.c
gcc -o child child.c
./parent
你会看到从阅读
小孩在小孩: 从小孩读取小孩阅读退出
最好使用'dup2',它允许您指定要使用的新文件描述符。 – dreamlax 2010-08-13 01:11:36
谢谢,我可以做这个工作。 – 2010-08-13 16:04:31
您可以尝试从Glib的g_spawn_async_with_pipes
。
该函数运行一个进程并返回其输入/输出文件描述符。
我用它在我的C++程序:
gchar** cmd_argv;
g_shell_parse_argv("your command", &cmd_argc, &cmd_argv, NULL);
g_spawn_async_with_pipes
(NULL, //Working directory, Inherited from parent (our program)
cmd_argv,
NULL, //Null to inherit environment variables from parent
G_SPAWN_SEARCH_PATH, //Flags
NULL,
NULL,
NULL, //Returns the process ID of child (which runs from our program)
&stdin_fd, //Standard input (file descriptor)
&stdout_fd, //Standard output (file descriptor)
&stderr_fd, //Standard error (file descriptor)
NULL); //GError*
...
//we have to free cmd_argv
for (int i = 0; i < cmd_argc; ++i) g_free (cmd_argv [i]);
stdin_fd
,stdout_fd
和stderr_fd
是整数(文件描述符):
gchar* out;
GIOChannel* io = g_io_channel_unix_new(stdout_fd); //g_io_channel_win32_new_fd
while(g_io_channel_read_line(io, &out, NULL, NULL, NULL) == G_IO_STATUS_NORMAL)
{
//...
g_free(out);
}
但是它不是一个C++库,但可能是有用的(当你想用C++编写GTK应用程序时)。
您的标签提示了一个linux解决方案,但文本显示“不是只有unix”,所以只有一个* nix解决方案是否可行? – 2010-08-12 14:07:21
我将文本更改为linux,因为我正在使用它,但是,* nix解决方案应该没问题。 – 2010-08-12 14:15:52