博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux 进程通信(System V) 第一节 ------> 管道 pipe
阅读量:4053 次
发布时间:2019-05-25

本文共 3024 字,大约阅读时间需要 10 分钟。

简介:
一.
#include <unistd.h>
int pipe(int fd[2]); 
 
 
//!>注意参数是fd[0]是读的文件描述符,fd[1]是用来写的文件描述符
一般用于 “父子进程” 之间的通信!因为pipe是没有标志的,所以只能在一个进程集中运作!
“单向pipe”:
 
 
 
 
 
 
父进程创建好 pipe 后,同时通过 fork() 创建一个子进程,然后父进程就可以关闭自己这端的“读进程”,因为 
父进程就是将数据写入子进程的,所以无须 “读”,然后子进程就关闭自己的“写”,这样就形成一个 “单向” 的 pipe。
“双向pie”:( 可以用于CS )
 
 
 
 
创建两个pipe就可以了,其实也就是相当于加一个 “单向”pipe
二.
 
 
 
 
关于 fork函数
 
 
 
 
对于fork的返回值:对于父进程返回的是子进程的ID号(肯定是大于0的),对于子进程返回的是0
所以可以通过 if( pid = fork() > 0 ) 和 if( pid == 0 )来判断是父进程还是子进程在执行
三.
 
 
 
其他
 
 
 
对于 pipe而言,创建 ok后,在子进程和父进程中都会有一个此管道(pipe)的读和写的接口!操作value是相同的fd[0]和fd[1]
对于 test.c 中的为例:
 
 
 
 
 
 
由于是多进程编程,那么对于test.c代码而言,应该是有“子进程”和“父进程”都可以执行的!也就是说在fork后程序就是分成两部分,主进程和子进程。
 
 
 
 
 
 
我们可以测试:
 
 
 
 
 
 
如果是printf("on ");那么可以输出两次 on,分别是父进程和子进程输出的,但是if是printf(" on \n");那么只输出一次。
 
 
 
 
 
 
原因:printf的机制是:遇到"\n"就会直接输出,if没有,那么只是储存在缓存中,然后一起输出。
 
 
 
 
 
 
 
 
 
所以if有"\n",那么就是父进程先让其输出了,那么在父进程的空间空就没有保存printf中的缓存数据了!!!所以子进程就没有继承到,所以就不会输出!!!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
也就是说:父进程的printf 空间缓存区也被继承!!!!!!!!!!!!!!!!!!!!!
 
 
 
 
 
 
getpid():获得本进程的ID
 
 
 
 
 
 
getppid():获得父进程的ID 
 
 
四.参考代码:
//!>
//!> 单向 pipe实例 
 
 
//!>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
int g_num =0; 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> 全局变量:用来测试父进程和子进程的独立空间
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> 我们可以知道全局变量在子进程和父进程中是有自己的独立空间的!
int main()
{
 
 
 
int n,fd[2]; 
 
 
 
 
 
 
 
 
 
 
 
//!> fd 是描述符
 
 
 
pid_tpid; 
 
 
 
 
 
 
 
 
 
 
 
//!> 保存的是创建的进程的 ID
 
 
 
charline[100]; 
 
 
 
 
 
 
 
 
 
 
 
//!> 相当于是一个缓存
 
 
 
int num = 0; 
 
 
 
 
 
 
 
 
 
 
 
//!> 也是独立的~~~
 
 
 
printf(" on"); 
 
 
 
 
 
 
 
 
 
 
 
//!> ATTENTION 
printf(" on\n");
 
 
 
if( pipe( fd) < 0) 
 
 
 
 
 
 
 
 
//!> 此处就是创建pipe,成功则返回0,if失败则返回-1
 
 
 
{
 
 
 
 
 
 
exit(0);
 
 
 
}
 
 
 
 
 
 
if( ( pid =fork() ) < 0) 
 
 
 
 
 
//!> 创建子进程
 
 
 
{
 
 
 
 
 
 
exit(0);
 
 
 
}
 
 
 
else if( pid> 0 )
 
 
 
{
 
 
 
 
 
 
close(fd[0]);
 
 
 
 
 
 
write(fd[1],"I am your father...\n", 19);
 
 
 
 
 
 
 
 
 
 
 
 
g_num++;
 
 
 
 
 
 
num++;
 
 
 
 
 
 
printf("\nFather g_num:%d 
 
 
num: %d\n", g_num,num); 
 
 
 
 
 
 
 
 
printf("\nMYID : %d 
 
 
Parent ID : %d 
\n", getpid(), getcpid());
 
 
 
}
 
 
 
else 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> == 0 当前进程(也就是刚刚创建的子进程)
 
 
 
{
 
 
 
 
 
 
close( fd[1]);
 
 
 
 
 
 
n = read(fd[0], line, 100 );
 
 
 
 
 
 
write(STDOUT_FILENO, line, n ); 
 
 
//
 
 
 
 
 
 
g_num++;
 
 
 
 
 
 
num++;
 
 
 
 
 
 
printf("\nChild g_num:%d 
 
 
num: %d\n", g_num, num);
 
 
 
 
 
 
printf("\nMYID : %d 
 
 
Parent ID : %d 
\n", getpid(), getppid());
 
 
 
}
 
 
 
printf(" ok"); 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
return0;
}
//!>
//!> 双向 pipe 实例
//!>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
 
 
 
int fd_1[2],fd_2[2]; 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> 双向 pipe 的 values、
 
 
 
charcData[100];
 
 
 
pid_tpid;
 
 
 
 
 
 
if( pipe(fd_1 ) < 0) 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> create the pipe_1
 
 
 
{
 
 
 
 
 
 
printf("\n创建第一个 pipe 失败!\n");
 
 
 
 
 
 
exit( 0);
 
 
 
}
 
 
 
 
 
 
if( pipe(fd_2 ) < 0) 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> create the pipe_2
 
 
 
{
 
 
 
 
 
 
printf("\n创建第二个 pipe 失败!\n");
 
 
 
 
 
 
exit( 0);
 
 
 
}
 
 
 
if( ( pid =fork() ) < 0) 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> false to create a new process
 
 
 
{
 
 
 
 
 
 
printf("\n创建进程失败!\n");
 
 
 
 
 
 
exit( 0);
 
 
 
}
 
 
 
else if( pid== 0 ) 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> 也就是fork返回的子进程...
 
 
 
{
 
 
 
 
 
 
//!> 子进程也需要发送 data 到 pipe
 
 
 
 
 
 
close(fd_2[0] );
 
 
 
 
 
 
char str[30]= "I am your child!";
 
 
 
 
 
 
write(fd_2[1], str, strlen( str )); 
 
 
 
 
 
//!> 第二个pipe是子进程发送data,父进程接受data
 
 
 
 
 
 
 
 
 
 
 
 
//!> 子进程也需要接受父进程的 data
 
 
 
 
 
 
close(fd_1[1] );
 
 
 
 
 
 
int n =read( fd_1[0], cData, 100); 
 
 
 
 
 
//!> 第一个pipe是父进程发送data,子进程接受data
 
 
 
 
 
 
write(STDOUT_FILENO, cData, n );
 
 
 
}
 
 
 
else 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//!> fork 返回的是子进程的ID,肯定是大于0的,所以此处执行的是父进程的code
 
 
 
{
 
 
 
 
 
 
//!> 父进程也需要发送 data 到 pipe
 
 
 
 
 
 
close(fd_1[0] );
 
 
 
 
 
 
char str[30]= "I am your father!";
 
 
 
 
 
 
write(fd_1[1], str, strlen( str )); 
 
 
 
 
 
//!> 第二个pipe是子进程发送data,父进程接受data
 
 
 
 
 
 
 
 
 
 
 
 
//!> 父进程也需要接受父进程的 data
 
 
 
 
 
close(fd_2[1] );
 
 
 
 
 
 
int n =read( fd_2[0], cData, 100); 
 
 
 
 
 
//!> 第一个pipe是父进程发送data,子进程接受data
 
 
 
 
 
 
write(STDOUT_FILENO, cData, n );
 
 
 
}
 
 
 
return0;
}

转载地址:http://vmaci.baihongyu.com/

你可能感兴趣的文章
BSP_WINCE_ARM_A8_User_Guide
查看>>
Catalog Item & Build
查看>>
AS提交代码到gitee
查看>>
ov2656
查看>>
android 休眠唤醒
查看>>
AT指令
查看>>
ov5640 regs
查看>>
Wince6.0 添加中文支持
查看>>
offline install deb software
查看>>
ubuntu12.04 64bit JB4.2.2
查看>>
11月前做好准备了吗?
查看>>
十月,广州
查看>>
就这样过了一个星期
查看>>
这两天在发呆
查看>>
百年暨南
查看>>
test
查看>>
数据库笔试题
查看>>
chances!I would let it go any more!
查看>>
何为程序员的理想生活方式
查看>>
大二你能做什么
查看>>