1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > pipe 半双工_linux进程间通信之管道(无名管道pipe)实现全双工双向通信

pipe 半双工_linux进程间通信之管道(无名管道pipe)实现全双工双向通信

时间:2023-06-23 23:34:46

相关推荐

pipe 半双工_linux进程间通信之管道(无名管道pipe)实现全双工双向通信

管道是什么:

1. 管道只能用于具有亲缘关系的进程之间通信。

2.管道是一种单工或者说半双工的通信方式,传递信息的方向是固定的,只能由一端传递到另一端。

头文件及函数原型:

#include

int pipe(int fd[2]);

当用pipe 创建管道后,两个文件描述符fd[0],fd[1]就可以使用了,其中fd[0]用于读取,fd[1]用于写入。调用管道pipe返回值0表示成功,返回值-1表示失败。

pipe函数创建管道后,接着fork出子进程,子进程继承父进程管道。

代码举例来看:

#include

#include

#include

#include

#include

#define MAX_DATA_LEN 256

#define DELAY_TIME 1

int main() {

pid_t pid;

char buf[MAX_DATA_LEN];

const char *data="Pipe Test";

int real_read,real_write;

int pipe_fd[2];

memset((void*)buf,0,sizeof(buf));

if(pipe(pipe_fd)<0){

perror("Pipe create error!\n");

exit(1);

}

if ((pid=fork())<0) {

perror("Fork error!\n");

exit(1);

} else if (pid==0) {

close(pipe_fd[1]);

sleep(DELAY_TIME*3);

if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {

printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);

}

close(pipe_fd[0]);

exit(0);

} else {

close(pipe_fd[0]);

sleep(DELAY_TIME);

if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {

printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);

}

close(pipe_fd[1]);

waitpid(pid,NULL,0);

exit(0);

}

}

复制代码

运行输出:

Parent write 9 bytes into pipe: 'Pipe Test'.

Child receive 9 bytes from pipe: 'Pipe Test'.

上述代码只能从父进程向子进程传递,如何从子进程向父进程传递呢?我们看到父进程关闭了管道读取端“close(pipe_fd[0]);”,子进程关闭了管道写入端“close(pipe_fd[1]);”,如果取消关闭这两个端,是否能够实现子进程向父进程传递呢。

父进程先发送,子进程接收,然后子进程再发送,父进程再接收,实现全双工互相通信,期望运行结果如下:

Parent write 9 bytes into pipe: 'Pipe Test'.

Child receive 9 bytes from pipe: 'Pipe Test'.

Child write 9 bytes from pipe: 'Pipe Test'.

Parent receive 9 bytes from pipe: 'Pipe Test'.

修改代码如下:

#include

#include

#include

#include

#include

#define MAX_DATA_LEN 256

#define DELAY_TIME 1

int main() {

pid_t pid;

char buf[MAX_DATA_LEN];

const char *data="Pipe Test";

int real_read,real_write;

int pipe_fd[2];

memset((void*)buf,0,sizeof(buf));

if(pipe(pipe_fd)<0){

perror("Pipe create error!\n");

exit(1);

}

if ((pid=fork())<0) {

perror("Fork error!\n");

exit(1);

} else if (pid==0) {

//close(pipe_fd[1]);

sleep(DELAY_TIME*3);

if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {

printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);

}

if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {

printf("Child write %d bytes into pipe: '%s'.\n",real_write,data);

}

close(pipe_fd[0]);

exit(0);

} else {

//close(pipe_fd[0]);

sleep(DELAY_TIME);

if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {

printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);

}

if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {

printf("Parent receive %d bytes from pipe: '%s'.\n",real_read,buf);

}

close(pipe_fd[1]);

waitpid(pid,NULL,0);

exit(0);

}

}

复制代码

但是实际运行如下:

Parent write 9 bytes into pipe: 'Pipe Test'.

Parent receive 9 bytes from pipe: 'Pipe Test'.

可以看到,父进程发送的数据被父进程自己接收了,子进程读不到数据被阻塞了。显然这种方法不行。

因为管道是单工的,只能固定从一个方向传递到另一个方向。

要实现互相通信,一个管道是不行的,可以创建两个管道,一个管道是父写子读,另一个是子写父读。

代码如下:

#include

#include

#include

#include

#include

#define MAX_DATA_LEN 256

#define DELAY_TIME 1

int main() {

pid_t pid;

char buf[MAX_DATA_LEN];

const char *data="Pipe Test";

int real_read,real_write;

int pipe_fd[2],pipe_fd2[2];

memset((void*)buf,0,sizeof(buf));

if(pipe(pipe_fd)<0){

perror("Pipe create error!\n");

exit(1);

}

if(pipe(pipe_fd2)<0){

perror("Pipe create error!\n");

exit(1);

}

if ((pid=fork())<0) {

perror("Fork error!\n");

exit(1);

} else if (pid==0) {

close(pipe_fd[1]);

close(pipe_fd2[0]);

sleep(DELAY_TIME*3);

if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {

printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);

}

if ((real_write=write(pipe_fd2[1],data,strlen(data)))>0) {

printf("Child write %d bytes into pipe: '%s'.\n",real_write,data);

}

close(pipe_fd[0]);

close(pipe_fd2[1]);

exit(0);

} else {

close(pipe_fd[0]);

close(pipe_fd2[1]);

sleep(DELAY_TIME);

if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {

printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);

}

if ((real_read=read(pipe_fd2[0],buf,MAX_DATA_LEN))>0) {

printf("Parentreceive %d bytes from pipe: '%s'.\n",real_read,buf);

}

close(pipe_fd[1]);

close(pipe_fd2[0]);

waitpid(pid,NULL,0);

exit(0);

}

}

复制代码

运行结果:

Parent write 9 bytes into pipe: 'Pipe Test'.

Child receive 9 bytes from pipe: 'Pipe Test'.

Child write 9 bytes into pipe: 'Pipe Test'.

Parentreceive 9 bytes from pipe: 'Pipe Test'.

可以看到,创建了两个管道 “int pipe_fd[2],pipe_fd2[2];”,

pipe_fd 是父写子读,pipe_fd2是子写父读,通过两个管道,实现了进程的全双工互相通信。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。