Linux进程间通信:管道及有名管道(3)

文章作者 100test 发表时间 2007:03:14 16:40:52
来源 100Test.Com百考试题网


向管道中写入数据:

向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞。

注:只有在管道的读端存在时,向管道中写入数据才有意义。否则,向管道中写入数据的进程将收到内核传来的SIFPIPE信号,应用程序可以处理该信号,也可以忽略(默认动作则是应用程序终止)。对管道的写规则的验证1:写端对读端存在的依赖性

#include 

#include 

main()

{

int pipe_fd[2].

pid_t pid.

char r_buf[4].

char* w_buf.

int writenum.

int cmd.



memset(r_buf,0,sizeof(r_buf)).

if(pipe(pipe_fd)<0)

{

printf("pipe create error\n").

return -1.

}



if((pid=fork())==0)

{

close(pipe_fd[0]).

close(pipe_fd[1]).

sleep(10). 

exit().

}

else if(pid>0)

{

sleep(1). //等待子进程完成关闭读端的操作

close(pipe_fd[0]).//write

w_buf="111".

if((writenum=write(pipe_fd[1],w_buf,4))==-1)

printf("write to pipe error\n").

else 

printf("the bytes write to pipe is %d \n", writenum).



close(pipe_fd[1]).

} 

}

则输出结果为: Broken pipe,原因就是该管道以及它的所有fork()产物的读端都已经被关闭。如果在父进程中保留读端,即在写完pipe后,再关闭父进程的读端,也会正常写入pipe,读者可自己验证一下该结论。因此,在向管道写入数据时,至少应该存在某一个进程,其中管道读端没有被关闭,否则就会出现上述错误(管道断裂,进程收到了SIGPIPE信号,默认动作是进程终止)对管道的写规则的验证2:linux不保证写管道的原子性验证

#include 

#include 

#include 

main(int argc,char**argv)

{

int pipe_fd[2].

pid_t pid.

char r_buf[4096].

char w_buf[4096*2].

int writenum.

int rnum.

memset(r_buf,0,sizeof(r_buf)). 

if(pipe(pipe_fd)<0)

{

printf("pipe create error\n").

return -1.

}



if((pid=fork())==0)

{

close(pipe_fd[1]).

while(1)

{

sleep(1). 

rnum=read(pipe_fd[0],r_buf,1000).

printf("child: readnum is %d\n",rnum).

}

close(pipe_fd[0]).



exit().

}

else if(pid>0)

{

close(pipe_fd[0]).//write

memset(r_buf,0,sizeof(r_buf)). 

if((writenum=write(pipe_fd[1],w_buf,1024))==-1)

printf("write to pipe error\n").

else 

printf("the bytes write to pipe is %d \n", writenum).

writenum=write(pipe_fd[1],w_buf,4096).

close(pipe_fd[1]).

} 

}

输出结果:

the bytes write to pipe 1000

the bytes write to pipe 1000 //注意,此行输出说明了写入的非原子性

the bytes write to pipe 1000

the bytes write to pipe 1000

the bytes write to pipe 1000

the bytes write to pipe 120 //注意,此行输出说明了写入的非原子性

the bytes write to pipe 0

the bytes write to pipe 0

......

结论:

写入数目小于4096时写入是非原子的!

如果把父进程中的两次写入字节数都改为5000,则很容易得出下面结论:

写入管道的数据量大于4096字节时,缓冲区的空闲空间将被写入数据(补齐),直到写完所有数据为止,如果没有进程读数据,则一直阻塞。



相关文章


Linux操作系统的X86汇编程序设计(2)
Linux操作系统的X86汇编程序设计(1)
Linux进程间通信:管道及有名管道(3)
Linux进程间通信:管道及有名管道(1)
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛