您的位置:首页 > 运维架构 > Linux

linux中匿名管道和命名管道

2017-03-09 16:43 309 查看

管道

匿名管道

1、创建管道和父子进程,子进程关闭读端,父进程关闭写端,子进程写,父进程读。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int pipefd[2] = {0,0};
if(pipe(pipefd) < 0){
perror("pipe");
return 1;
}
pid_t id = fork();// creat child progress
if(id < 0){
perror("fork");
return 2;
}else if(id == 0){//child->write
close(pipefd[0]);
const char* msg = "hello world";
int count = 5;
while(count){
write(pipefd[1],msg,strlen(msg));
count--;
sleep(1);
}
close(pipefd[1]);
exit(0);

}else{//father->read
close(pipefd[1]);
int count = 5;
char buf[128];
while(count){
ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1);
if(_s > 0){
buf[_s] = '\0';
printf("%s\n",buf);
}else if(_s == 0){
printf("close\n");
break;
}else{
perror("read");
return 3;
}
count--;
}
close(pipefd[0]);
}
return 0;
}




2、如果所有指向管道写端的文件描述符都关闭了(管道写端的引用计数等于0),而仍然有进程 从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int pipefd[2] = {0,0};
if(pipe(pipefd) < 0){
perror("pipe");
return 1;
}
pid_t id = fork();// creat child progress
if(id < 0){
perror("fork");
return 2;
}else if(id == 0){//child->write
close(pipefd[0]);
const char* msg = "hello world";
int count = 5;
while(count){
write(pipefd[1],msg,strlen(msg));
count--;
sleep(1);
}
close(pipefd[1]);
exit(0);

}else{//father->read
close(pipefd[1]);
int count = 5;
char buf[128];
while(1){
ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1);
if(_s > 0){
buf[_s] = '\0';
printf("child->father:%s\n",buf);
}else if(_s == 0){
printf("pipe write is close\n");
break;
}else{
perror("read");
return 3;
}
count--;
}
close(pipefd[0]);
}
return 0;
}




3、如果有指向管道写端的文件描述符没关闭(管道写端的引用计数大于0),而持有管道写端的 进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int pipefd[2] = {0,0};
if(pipe(pipefd) < 0){
perror("pipe");
return 1;
}
pid_t id = fork();// creat child progress
if(id < 0){
perror("fork");
return 2;
}else if(id == 0){//child->write
close(pipefd[0]);
const char* msg = "hello world";
int count = 5;

while(1){
write(pipefd[1],msg,strlen(msg));
count--;
if(count == 0)
{
sleep(5);
count--;
}
sleep(1);
}
close(pipefd[1]);
exit(0);
}else{//father->read
close(pipefd[1]);
int count = 5;
char buf[128];
while(1){
ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1);
if(_s > 0){
buf[_s] = '\0';
printf("child->father:%s\n",buf);
}else if(_s == 0){
printf("pipe write is close\n");
break;
}else{
perror("read");
return 3;
}
count--;
}
close(pipefd[0]);
}
return 0;
}




4、如果所有指向管道读端的文件描述符都关闭了(管道读端的引用计数等于0),这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int pipefd[2] = {0,0};
if(pipe(pipefd) < 0){
perror("pipe");
return 1;
}
pid_t id = fork();// creat child progress
if(id < 0){
perror("fork");
return 2;
}else if(id == 0){//child->write
close(pipefd[0]);
const char* msg = "hello world";
int count = 5;

while(1){
write(pipefd[1],msg,strlen(msg));
count--;
sleep(1);
}
close(pipefd[1]);
exit(0);
}else{//father->read
close(pipefd[1]);
int count = 5;
char buf[128];
while(1){
ssize_t _s = read(pipefd[0],buf,sizeof(buf)-1);
if(_s > 0){
buf[_s] = '\0';
printf("child->father:%s\n",buf);
}else if(_s == 0){
printf("pipe write is close\n");
break;
}else{
perror("read");
return 3;
}
count--;
if(count == 0){
close(pipefd[0]);
break;
}
}
}
int status = 0;
pid_t ret = waitpid(id,&status,0);
if(ret > 0){
printf("exit code: %d,signl: %d\n",(status>>8)&0xff,status&0xff);
}
return 0;
}




命名管道

1、client端

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<string.h>
int main()
{

int fd = open("./fifo",O_WRONLY);
if(fd < 0){
perror("open");
return 2;
}
char buf[128];
while(1){
printf("Please Enter# ");
fflush(stdout);
ssize_t s = read(0,buf,sizeof(buf));
if(s > 0){
buf[s-1] = '\0';
write(fd,buf,strlen(buf));
}else if(s == 0){
printf("client quit! I should quit!\n");
break;
}else{
perror("read");
}
}
close(fd);
return 0;
}


2、server端

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
int main()
{
umask(0);
if(mkfifo("./fifo",0666|S_IFIFO) < 0){
perror("mkfifo");
return 1;//shell look
}

int fd = open("./fifo",O_RDONLY);
if(fd < 0){
perror("open");
return 2;
}
char buf[128];
while(1){
ssize_t s = read(fd,buf,sizeof(buf));
if(s > 0){
buf[s] = '\0';
printf("client# %s\n",buf);
}else if(s == 0){
printf("client quit! I should quit!\n");
break;
}else{
perror("read");
}
}
close(fd);
return 0;
}


client端输入什么,server端输出什么,结果如下所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: