从 C 中的管道传递的参数

发布于 2024-12-01 06:05:42 字数 637 浏览 1 评论 0原文

我正在尝试通过管道和 execvp 传递令牌...但是我的问题是第一个和第二个子进程收到相同的令牌...如果有第三个或更多令牌该怎么办?

    int pipedes[2];
    pipe(pipedes);

    pid_t pid = fork();
    if (pid == 0) {
            dup2(filedes[1], 1);

            execvp(argv[0], argv);
    } else {
            close(pipedes[1]);
    }

    pid = fork();
    if (pid == 0) {
            dup2(pipedes[0], 0);

            execvp(arg[0], argv);
    }

    wait(&pid);

和代币

strtok(line, "|");

            pipe(line);
            while (1) {

                    line= strtok(NULL, "|");

                    pipe(line);
            }

I am trying to pass tokens through pipes and execvp... However my problem is that 1st and 2nd child processes receive the same tokens... and what can be done if there is a third or more tokens?

    int pipedes[2];
    pipe(pipedes);

    pid_t pid = fork();
    if (pid == 0) {
            dup2(filedes[1], 1);

            execvp(argv[0], argv);
    } else {
            close(pipedes[1]);
    }

    pid = fork();
    if (pid == 0) {
            dup2(pipedes[0], 0);

            execvp(arg[0], argv);
    }

    wait(&pid);

and tokens

strtok(line, "|");

            pipe(line);
            while (1) {

                    line= strtok(NULL, "|");

                    pipe(line);
            }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不回头走下去 2024-12-08 06:05:42

这句话:

pipe(line);

纯属无稽之谈。它创建两个新的文件描述符并用它们覆盖 line 的前 2 x sizeof(int) 字节。您的生产者进程应该将令牌写入标准输出,而您的消费者进程应该从标准输入读取它们。

顺便说一句,您的子进程似乎使用完全相同的参数执行与父进程相同的可执行文件。每个人如何知道自己是生产者还是消费者?

This line:

pipe(line);

is nonsense. It creates two new file descriptors and overwrites the first 2 x sizeof(int) bytes of line with them. Your producer process should be writing the tokens to stdout and your consumer process should read them from stdin.

By the way, your child processes appear to execute the same executable as the parent with exactly the same arguments. How does each one know whether it is the producer or consumer?

段念尘 2024-12-08 06:05:42

如果您想让两个不同的子进程执行相同的可执行文件,但使用两个不同的命令,则需要为每个子进程设置两个不同的管道。您设置管道的过程也是不正确的,因为您允许孩子让管道保持打开状态。

#include <sys/wait.h>
#include <unistd.h>
#include <
int pipedes_child_1[2];
int pipedes_child_2[2];

pipe(pipedes_child_1);

pid_t child = fork();

if (!child)
{
    dup2(pipedes_child_1[0], 0);
    close(pipedes_child_1[1]); //without this, child with hang on read()
    execvp(argv[0], argv);
}
else
{
    close(pipedes_child_1[0];
}

pipe(pipedes_child_2);

child = fork();

if (!child)
{
    dup2(pipedes_child_2[0], 0);
    close(pipe_des_child_2[1]);  //without this, child with hang on read()
    execvp(argv[0], argv);
}
else
{
    close(pipedes_child_2[0]);
}

//...write tokens to each child via pipedes_child_X[1];

//wait for all the children
int return_val = 0;
while(wait(&return_val) > 0 || errno != EINTR);

请记住,由于您正在调用 execvp(argv[0], argv),因此您实际上将无限递归地“扇”进程,因为您只是用以下命令调用当前进程当前的争论......我认为这不是你想要的。为了防止这种情况,假设您将子进程指定为主父可执行文件的参数,并在调用 exec 系列之一时将这些值作为要启动的程序传递。功能。例如:

//child_1 executable that will take no arguments and read from the pipe
execlp(argv[1], argv[1], (char*)0);

//child_2 executable that will take no arguments and read from the pipe
execlp(argv[2], argv[2], (char*)0);

If you want to have two different child executing the same executable, but using two different commands, you will need to setup two different pipes for each child process. Your process for setting up the pipes is also incorrect since you allow the child to leave a pipe open.

#include <sys/wait.h>
#include <unistd.h>
#include <
int pipedes_child_1[2];
int pipedes_child_2[2];

pipe(pipedes_child_1);

pid_t child = fork();

if (!child)
{
    dup2(pipedes_child_1[0], 0);
    close(pipedes_child_1[1]); //without this, child with hang on read()
    execvp(argv[0], argv);
}
else
{
    close(pipedes_child_1[0];
}

pipe(pipedes_child_2);

child = fork();

if (!child)
{
    dup2(pipedes_child_2[0], 0);
    close(pipe_des_child_2[1]);  //without this, child with hang on read()
    execvp(argv[0], argv);
}
else
{
    close(pipedes_child_2[0]);
}

//...write tokens to each child via pipedes_child_X[1];

//wait for all the children
int return_val = 0;
while(wait(&return_val) > 0 || errno != EINTR);

Keep in mind, that since you are calling execvp(argv[0], argv), you are actually going to make an infinitely recursive "fan" of processes since you're just recalling the current process with the current arguments ... I don't think that's what you're wanting. To prevent that, let's say you specify the child processes as arguments to the main parent executable, and pass those values as the programs to launch when calling one of the exec family of functions. So for instance:

//child_1 executable that will take no arguments and read from the pipe
execlp(argv[1], argv[1], (char*)0);

//child_2 executable that will take no arguments and read from the pipe
execlp(argv[2], argv[2], (char*)0);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文