我正在尝试编写简单的控制台应用程序,它从用户那里读取文本,然后将小写字母更改为大写字母,最后在控制台中打印结果。 当我只使用一个管道时它工作正常(例如,不从控制台读取文本),但当我使用两个时它的工作完全不可预测。
“[Write]”不应该等待“[To upper]”直到它发送文本吗?
我得到以下输出:
[Write] Waiting for txt to diplay.
[To upper] Waiting for txt to change.
[Write] Received following txt:
[To upper] Received txt ().
[To upper] Changed txt send to [Write] ().
[Scan] Type your txt:
[Scan] Txt received. Sending to [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 );
}
}
最佳答案
我认为您需要了解一些事情才能理解问题。首先,在 fork()
之后,无法保证哪个进程先运行。其次,如果管道的另一端未打开以进行写入,read()
会立即返回零值。
您指望进程以特定顺序运行,以便在进行任何读取之前管道在两侧都打开。由于这种情况并不总是发生,read()
并不总是阻塞。
您可以通过在 fork()
之前打开所有管道的两端来解决这个问题。所有进程都将在管道的两端都有文件描述符。只需在相应进程中不需要的文件描述符上调用 close()
。
关于c - 在 C/Linux 中使用命名管道和 fork,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30328987/