Linux C网络编程

324 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天

管道

system()\exec()\fork()

进程通信:信号量、共享内存、消息队列、管道

管道:实质缓冲区,进行进程之间的通信 管道数据用过之后就消失

  管道文件 p 伪文件

命名管道:fifo(有名字,类似于文件)

匿名管道:pipe(没有名字)   ls /home | grep t

  进程1(写操作) --> 临时缓冲区(管道)-->进程2( 读操作)

一、pipe()函数:建立一个管道  

 #include  <unistd.h>

int pipe(int filedes[2]);

使用pipe前,需要定义一个一维数组,包括两个成员,未来

作为文件描述符,一个控制读端、另一个控制写端。

常常配合fork,来作为两个亲缘关系进程的通信。

 

(一)读管道:

1.管道有数据。read返回实际读到的字节数。

2.管道无数据:1)无写端,read返回0

             2)有写端,read阻塞等待。

(二)写管道:

1无读端,异常终止(sigpie 导致)

2.有读端

1)管道已满,阻塞等待

2)管道未满,返回写出的字节个数。

sleep(10)

(三)管道阻塞和管道操作的原子性

当管道的写端没有关闭时,如果写请求的字节数目大于阈值PIPE_BUF,写操作的返回值是管道中目前的数据字节数;如果写请求的字节数目不大于阈值PIPE_BUF,则返回管道中现有数据字节数。

128k  200k  写两次 等待读进程读后,继续写。

如果管道数据已满,写进程阻塞,等待sleep读进程取走数据;

写缓冲 128k,读缓冲10k  应读13次

命名管道(FIFO)

pipe.c:文件 write、read函数

       进程 fork函数

       进程通信pipe函数 命名管道:fifo文件

shell命令:mkfifo 文件名

程序建立 mkfifo( )函数

#include <sys/types.h>

#include <sys/stat.h>

Int  mkfifo(const  *path_name, mode_t  mode)

建立成功后,应用管道,把它作为文件进行操作。

建立两个进程,对所建管道分别进行读、写操作。

 

写入管道的内容,执行时看不到;把管道内容输出到屏幕即可见。

读进程代码:

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <string.h>

int main(int argc,char *argv[])

{

 int fd,len;

 char buf[1024];

 if(argc<2)

 {printf("enter like ./out fifoname\n");

  return -1;

}

 fd=open(argv[1],O_RDONLY);

 while(1)

{

  len=read(fd,buf,sizeof(buf));

   write(STDOUT_FILENO,buf,len);

   sleep(2);  

 }

 close(fd);

return 0;

}

写进程代码:

#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <string.h>

int main(int argc,char *argv[])

{

 int i,fd,len;

 char buf[1024];

 if(argc<2)

 {printf("enter like ./out fifoname\n");

 }

 fd=open(argv[1],O_WRONLY);

 if(fd<0)printf("open failure");

 i=0;

 while(1)

 {

   sprintf(buf,"hello myfifo %d\n",i++);

   write(fd,buf,strlen(buf));

   sleep(2);  

 }

 close(fd);

return 0;

}