Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.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
如何从使用C和linux的用户那里获取键盘输入?_C_Linux_Pipe_Fork - Fatal编程技术网

如何从使用C和linux的用户那里获取键盘输入?

如何从使用C和linux的用户那里获取键盘输入?,c,linux,pipe,fork,C,Linux,Pipe,Fork,我必须制作一个简短的程序,创建两个子进程,每个子进程从键盘接受一个整数,并将它们写入管道,从那里父进程汇总它们并在屏幕上显示总数 我已经用scanf()写了一个,但是它冻结了,没有给我总数。如果可能的话,我如何使它与scanf或任何其他方式一起工作 #include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> int pipe(int pd[

我必须制作一个简短的程序,创建两个子进程,每个子进程从键盘接受一个整数,并将它们写入管道,从那里父进程汇总它们并在屏幕上显示总数

我已经用scanf()写了一个,但是它冻结了,没有给我总数。如果可能的话,我如何使它与scanf或任何其他方式一起工作

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int pipe(int pd[2]);
int main(int argc, char *argv[])
{

    int pd[2], sum=0, num=0;
    if(pipe(pd) == -1)
    for(int i = 0; i < 2; i++)
    {
        if(fork() == 0)
        {
            scanf("%d", num);
            if(write(pd[1], &num, sizeof(int)) == -1)
                printf("Error: Write()");           
        }
    }

    for(int j = 0; j < 2; j++)
    {
        wait(NULL);
        if(read(pd[0], &num, sizeof(int)) == -1)
            printf("Error: Read()");

        sum += num;
    }
    printf("Total: %d\n", sum);
}
#包括
#包括
#包括
#包括
内部管道(内部管道[2]);
int main(int argc,char*argv[])
{
int-pd[2],sum=0,num=0;
如果(管道(pd)=-1)
对于(int i=0;i<2;i++)
{
如果(fork()==0)
{
scanf(“%d”,num);
if(write(pd[1],&num,sizeof(int))=-1)
printf(“错误:Write()”);
}
}
对于(int j=0;j<2;j++)
{
等待(空);
if(读取(pd[0],&num,sizeof(int))=-1)
printf(“错误:Read()”);
sum+=num;
}
printf(“总计:%d\n”,总和);
}
这里有很多问题:

  • 您有
    if(pipe(pd)=-1)
    ,我假设您打算使用一个错误处理程序作为它的“then”子句,但您没有,因此只有在管道失败时才会生成子项,这基本上与您想要的相反
  • 您有
    scanf(“%d”,num)。您需要
    &num
    ,因为
    num
    还不是指针
  • 您需要从子进程
    返回
    退出
    ,否则它们将进入下一个循环并使用输出
只要把这些东西修好,就足以让它工作:

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int pipe(int pd[2]);
int main(int argc, char *argv[])
{

    int pd[2], sum=0, num=0;
    if(pipe(pd) == -1)
    {
        perror("pipe");
        return 1;
    }
    for(int i = 0; i < 2; i++)
    {
        if(fork() == 0)
        {
            scanf("%d", &num);
            if(write(pd[1], &num, sizeof(int)) == -1)
                printf("Error: Write()");
            return 0;
        }
    }

    for(int j = 0; j < 2; j++)
    {
        wait(NULL);
        if(read(pd[0], &num, sizeof(int)) == -1)
            printf("Error: Read()");

        sum += num;
    }
    printf("Total: %d\n", sum);
}
#包括
#包括
#包括
#包括
内部管道(内部管道[2]);
int main(int argc,char*argv[])
{
int-pd[2],sum=0,num=0;
如果(管道(pd)=-1)
{
佩罗(“管道”);
返回1;
}
对于(int i=0;i<2;i++)
{
如果(fork()==0)
{
scanf(“%d”和&num);
if(write(pd[1],&num,sizeof(int))=-1)
printf(“错误:Write()”);
返回0;
}
}
对于(int j=0;j<2;j++)
{
等待(空);
if(读取(pd[0],&num,sizeof(int))=-1)
printf(“错误:Read()”);
sum+=num;
}
printf(“总计:%d\n”,总和);
}
还有一些其他的事情你也应该解决,但它们并不是完全停止表演。下面是我突然想到的:

  • 您不需要声明自己的
    管道
    原型。unistd.h的那一个很好
  • 您应该处理
    fork
    scanf
    失败的情况
  • 您应该处理部分读取和写入
  • 分叉后,应在子级中关闭管道的读取端,在父级中关闭管道的写入端
  • 你应该考虑使用一个锁来控制读输入,这样它就不依赖于TTY线缓冲来可靠工作。
您需要在进程之间进行一些同步,以确保它们不会同时尝试从终端读取数据;否则,您无法确定哪一个将获得数据。还请注意,子进程将继续运行通过
if(fork()==0)
块,因此您可能希望在该块的末尾放置一个
\u exit()
。键入数字后是否按Enter键?@NateEldredge您能帮助实现同步吗?我知道我需要一个信号量或互斥量,但我不知道在运行代码时如何区分两个孩子。我还将把_exit()命令放在代码的末尾。@Joseph SIble恢复Monica是的,但它只是转到一个新的行。因为孩子们都做相同的事情,所以你不需要区分他们。它们都可以尝试锁定信号量;一个会成功,另一个会等到第一个解锁。