我正在尝试编写从用户读取文本的简单控制台应用程序,然后将小写更改为大写,最后在控制台中打印结果。 当我只使用一个管道时(例如没有从控制台读取文本)它工作正常,但当我使用两个管道时,它完全不可预测。
在发送短信之前,不应该'[写入]'等待'[上限]'?
我得到了以下输出:
[写入]等待txt显示。
[To upper]等待txt改变。
[写]收到以下txt:
[To upper]收到txt()。
[To upper]将txt发送更改为[Write]() [扫描]输入你的txt:
[扫描]收到Txt。发送至[To upper](y)
我的代码:
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#define SIZE 16
int main()
{
int i=0;
int f1,f2;
char x[SIZE]={0};
if( fork() )
{
if( fork() )//[Write]
{
f1=open("upper-write",O_RDONLY);
puts( "[Write] Waiting for txt to diplay." );
read( f1, &x, sizeof( x ) );
printf( "[Write] Received following txt: %s\n", x );
close( f1 );
}
else//[Scan]
{
puts( "[Scan] Type your txt: " );
//scanf ("%15s",x);//scanf not working now, so I change my char array by myself
x[0]='y';
f2=open("scan-upper",O_WRONLY);
printf( "[Scan] Txt received. Sending to [To upper] (%s)\n", x );
write( f2, &x, sizeof( x ) );
close( f2 );
}
}
else//[To upper]
{
puts( "[To upper] Waiting for txt to change." );
f2=open("scan-upper",O_RDONLY);
read( f2, &x, sizeof( x ) );
close( f2 );
printf( "[To upper] Received txt (%s).\n" ,x);
for(i=0;i<SIZE;i++)
if(x[i]>=97 && x[i] <=122)//lowercase -> uppercase
x[i]-=32;
f1=open("upper-write",O_WRONLY);
write( f1, &x, sizeof( x ) );
printf( "[To upper] Changed txt send to [Write] (%s).\n" ,x);
close( f1 );
}
}
答案 0 :(得分:2)
我认为你需要了解一些事情来理解这个问题。首先,在fork()
之后,无法保证首先运行哪个进程。其次,如果管道的另一端没有打开写入,read()
会立即返回值为零。
您依赖于按特定顺序运行的流程,以便在进行任何读取之前管道都在两侧打开。由于这并不总是发生,read()
并不总是阻止。
您可以通过在fork()
之前打开所有管道的两端来解决此问题。所有进程都会在管道的两端都有文件描述符。只需在相应流程中不需要的文件描述符上调用close()
即可。
答案 1 :(得分:-1)
你确定这不是因为你的非扫描进程没有关闭stdin吗?您可能希望在fork之后执行类似“close(0)”的操作。
或者,有popen(),这可能对这种东西很有趣。