加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

管道和流程

发布时间:2020-12-16 03:46:49 所属栏目:百科 来源:网络整理
导读:前提: 编写程序以向用户查询两个输入字符串.每个输入字符串应该是一个unix命令,允许使用参数.例如,输入1可以是ls -l,输入2可以是更多.然后程序将创建一个管道和两个子进程.第一个子进程将运行第一个输入中指定的命令.它将输出到管道而不是标准输出.第二个子
前提:
编写程序以向用户查询两个输入字符串.每个输入字符串应该是一个unix命令,允许使用参数.例如,输入1可以是ls -l,输入2可以是更多.然后程序将创建一个管道和两个子进程.第一个子进程将运行第一个输入中指定的命令.它将输出到管道而不是标准输出.第二个子进程将运行第二个输入中指定的命令.它将从管道输入而不是标准输入.父进程将等待其两个子进程完成,然后整个过程将重复.当输入’@’符号作为第一个命令时,执行将停止.这是我的代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(){

    /* Program Termination Symbol */
    const char terminate = '@';

    /* String delimiter */
    const char delimiter = ' ';

    /* Pipe file ID's */
    int fileID[2];

    /* Parent ID's */
    int pid1,pid2;

    /* String token */
    char * token,* token2;

    /* User input */
    char * user_input,line[100];

    user_input = (char *) malloc(100);

    /* Unix Commands */
    char * command1[10],*command2[10];

    for (int i=0; i<10; i++)
    {
    command1[i] = (char *)malloc(100*sizeof(char));
    command2[i] = (char *)malloc(100*sizeof(char));
    }

    /* Begin main program logic */

    printf("Please enter the first command: n");

    user_input = gets(line);

    while (user_input[0] != terminate)
    {
    token = (char *) malloc(100*sizeof(char));

    for (int i=0; i<10; i++)
        {
        if (i == 0)
        {
        token = strtok(user_input,&delimiter); 
        } else {
        token = strtok(NULL,&delimiter);
        }

        if (token != NULL)
        {
        strcpy(command1[i],token);
        } else {
        command1[i] = 0;
        }
        }

    printf("Please enter the second command: n");  
    user_input = gets(line);

    token2 = (char *) malloc(100*sizeof(char));

    for (int i=0; i<10; i++)
    {
        if (i == 0)
        {
        token2 = strtok(user_input,&delimiter);
        } else {
        token2 = strtok(NULL,&delimiter);
        }

        if (token2 != NULL)
        {
        strcpy(command2[i],token2);
        } else {
        command2[i] = 0;
        }
    }   


    /* Pipe and execute user commands */

    /* Create pipe */
    pipe(fileID);

    /* Create child processes */

    pid1 = fork();

    if (pid1 != 0)
    {
        pid2 = fork();
    }

    /* First child process */
    if (pid1 == 0)
    {
        dup2(fileID[1],1);
        execvp(command1[0],command1);
    }

    /* Second child process */
    if (pid2 == 0)
    {
        dup2(fileID[0],0);
        execvp(command2[0],command2);
    }   

    /* Wait for children to terminate */
    wait(&pid1);
    wait(&pid2);

    /* Repeat */
        printf("Please enter the first command: n");
    user_input = gets(line);
    }

    return 0;
}

我遇到的问题是我的等待.如果我有两个,这对我来说是有意义的(每个孩子一个等待)然后程序在执行第一个管道后冻结.如果我删除了第二个等待,那么程序将再次开始循环,但是不会接受除了enter之外的键盘输入,并且会产生段错误.因此,无论是等待,输入和输出都是……

Please enter the first command:
ls
Please enter the second command:
more
Pipe
Pipe.c
Pipe.c~

……然后它就锁起来了.如果我删除第二个等待,输入/输出是……

Please enter the first command:
ls
Please enter the second command:
more
Pipe
Pipe.c
Pipe.c~
Please enter the first command:
(I hit enter,nothing else will work)
Segmentation fault

有人有什么建议吗?这显然与等待这两个过程有关,但我对如何处理它感到茫然.

这个程序现在100%正常运行 – 非常感谢大家的帮助!堆栈溢出一直是互联网上最好的资源之一.非常感谢你花时间查看我的代码并给我你的建议.

解决方法

我同意torak所说的一切,但为了解决你的问题,你需要关闭你的管道.我认为你是“挂”,因为管道仍然是敞开的.

所以在父母中,就在“等待”之前,我会关闭管道.

close(fileID[0]);
close(fileID[1]);
wait(&pid_status);
wait(&pid_status);

然后,在每个execvp之前,我会关闭孩子不会使用的管道的末端:

close(fileID[0]);
dup2(fileID[1],1);
execvp(command1[0],command1);


close(fileID[1]);
dup2(fileID[0],0);
execvp(command2[0],command2);

这应该解决你的问题.除了torak提出的建议之外,我还建议使用fgets而不是gets来防止缓冲区溢出.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读