管道和流程

管道和流程,第1张

概述前提: 编写程序以向用户查询两个输入字符串.每个输入字符串应该是一个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:lsPlease enter the second command:morePipePipe.cPipe.c~

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

Please enter the first command:lsPlease enter the second command:morePipePipe.cPipe.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来防止缓冲区溢出.

总结

以上是内存溢出为你收集整理的管道和流程全部内容,希望文章能够帮你解决管道和流程所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1258473.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存