1、管道:
(1)、定义:特殊类型的文件,体现为两个文件描述符
(2)、特点:
a、半双工,同一时刻数据流向只有一个(父->子、子->父)
b、数据只能一端写入,一端读出
c、先入先出
d、双方要提前约定好数据的格式
e、没有名字,不存在于文件系统,只存在于内存中
f、数据是一次性的
g、有默认大小
h、只能在有公共祖先的进程间使用
(3)、函数
pipe: 创建无名管的并获得文件描述符
int fd[2]={};
pipe(fd);
注意:pipe在fork前面,如果pipe在fork后面,那父子进程各自创建了一个无名管道,通信的时候用的就不是同一个无名管道
write、read
(4)、读写特点:
read:读数据
带阻塞,如果管道中没有数据,read会阻塞直到管道中有数据为止,会读出数据并返回
write:写数据
带阻塞,管道的缓冲区写满了,write就会阻塞
缓冲区大小:64k
读端口全部关闭(2个),写进程再往里写数据,写进程会推出
fcntl:设置文件描述符为非阻塞
fcntl(fd[0],F_SETFL,O_NONBLOCK);
2、重定向:
文件描述符的复制:复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。
fd->a.c,1->stdout
实现1->a.c
函数:
dup:
close(1);//把1变成最小可用的
int fd_new = dup(fd);//1去复制fd的指向,1->a.c,fd_new=1
dup2:
dup2(fd,1);//注意第二个参数的范围:0-1023
注意:
1)、0、1、2的指向改变了,原本指向的标准输入、标准输出和标准错误就无法使用,所以需要把标准输入、标准输出和标准错误保存起来
2)、文件描述符在切换的过程中,因为指向的内容可能在stdout和普通文件中来回切换,要注意缓冲区的类型也在变化,所以为了避免缓冲区类型变化而造成的问题,可以选择使用系统调用函数(无缓冲区)
3、命名管道
(1)、定义:特殊类型的文件,存在于文件系统中
(2)、特点:
a、半双工,同一时刻数据的流向只有一个
b、先入先出
c、没有格式要求,要双方实现约定好
d、有名字,在文件系统中可以查看到,但是内容存在于内存中
e、数据时一次性的
f、对应缓冲区,有固定大小
g、创建过一次,以后就无需创建,可直接使用
h、可以实现不相关进程的通信
注意:如果进行复制,管道文件会变成普通文件,所以要注意,复制后的管道文件要进行删除并重新创建
(3)、函数:
mkfifo("./fifo",0777);
文件类型: p 管道文件
open:打开方式:已存在的方式,不能加O_CREAT
read、write
注意:命名管道的内容存在于内存中,如果进程结束,内存释放,命名管道中的内容也就没有了,使用的时候要注意,写进程的存活
(4)、读写特点:
1)、O_RDWR:
a、read是带阻塞的,有内容就读,没有内容就阻塞在这,直到命名管道中有数据为止
b、write是带阻塞的,缓冲区写满了,write就阻塞
2)、只读或只写(不位或O_NONBLOCK)
a、以只读或只写的方式打开命名管道,open会阻塞,直到其他进程以写或读的方式打开命名管道为止(open_read.c open_write.c)
b、read是带阻塞的
c、write是带阻塞的
d、写进程退出,read变为非阻塞;写进程再运行,read会恢复为阻塞(write_4.c read_4.c)
e、读进程退出,写进程再往命名管道中写数据,写进程也会退出(write_4.c read_4.c)
3)、只读或只写(位或O_NONBLOCK)
a、open:以只写方式并位或O_NONBLOCK打开命名管道,且没有任何进程以读的方式打开命名管道,会失败(non_write_open.c)
b、open:以只读方式并位或O_NONBLOCK打开命名管道,会成功(non_read_open.c)
c、write和read是非阻塞的
d、读进程退出后,写进程再向命名管道中写数据,写进程也会退出(non_read_open.c non_write_open.c)
(1)、定义:特殊类型的文件,体现为两个文件描述符
(2)、特点:
a、半双工,同一时刻数据流向只有一个(父->子、子->父)
b、数据只能一端写入,一端读出
c、先入先出
d、双方要提前约定好数据的格式
e、没有名字,不存在于文件系统,只存在于内存中
f、数据是一次性的
g、有默认大小
h、只能在有公共祖先的进程间使用
(3)、函数
pipe: 创建无名管的并获得文件描述符
int fd[2]={};
pipe(fd);
注意:pipe在fork前面,如果pipe在fork后面,那父子进程各自创建了一个无名管道,通信的时候用的就不是同一个无名管道
write、read
(4)、读写特点:
read:读数据
带阻塞,如果管道中没有数据,read会阻塞直到管道中有数据为止,会读出数据并返回
write:写数据
带阻塞,管道的缓冲区写满了,write就会阻塞
缓冲区大小:64k
读端口全部关闭(2个),写进程再往里写数据,写进程会推出
fcntl:设置文件描述符为非阻塞
fcntl(fd[0],F_SETFL,O_NONBLOCK);
2、重定向:
文件描述符的复制:复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。
fd->a.c,1->stdout
实现1->a.c
函数:
dup:
close(1);//把1变成最小可用的
int fd_new = dup(fd);//1去复制fd的指向,1->a.c,fd_new=1
dup2:
dup2(fd,1);//注意第二个参数的范围:0-1023
注意:
1)、0、1、2的指向改变了,原本指向的标准输入、标准输出和标准错误就无法使用,所以需要把标准输入、标准输出和标准错误保存起来
2)、文件描述符在切换的过程中,因为指向的内容可能在stdout和普通文件中来回切换,要注意缓冲区的类型也在变化,所以为了避免缓冲区类型变化而造成的问题,可以选择使用系统调用函数(无缓冲区)
3、命名管道
(1)、定义:特殊类型的文件,存在于文件系统中
(2)、特点:
a、半双工,同一时刻数据的流向只有一个
b、先入先出
c、没有格式要求,要双方实现约定好
d、有名字,在文件系统中可以查看到,但是内容存在于内存中
e、数据时一次性的
f、对应缓冲区,有固定大小
g、创建过一次,以后就无需创建,可直接使用
h、可以实现不相关进程的通信
注意:如果进行复制,管道文件会变成普通文件,所以要注意,复制后的管道文件要进行删除并重新创建
(3)、函数:
mkfifo("./fifo",0777);
文件类型: p 管道文件
open:打开方式:已存在的方式,不能加O_CREAT
read、write
注意:命名管道的内容存在于内存中,如果进程结束,内存释放,命名管道中的内容也就没有了,使用的时候要注意,写进程的存活
(4)、读写特点:
1)、O_RDWR:
a、read是带阻塞的,有内容就读,没有内容就阻塞在这,直到命名管道中有数据为止
b、write是带阻塞的,缓冲区写满了,write就阻塞
2)、只读或只写(不位或O_NONBLOCK)
a、以只读或只写的方式打开命名管道,open会阻塞,直到其他进程以写或读的方式打开命名管道为止(open_read.c open_write.c)
b、read是带阻塞的
c、write是带阻塞的
d、写进程退出,read变为非阻塞;写进程再运行,read会恢复为阻塞(write_4.c read_4.c)
e、读进程退出,写进程再往命名管道中写数据,写进程也会退出(write_4.c read_4.c)
3)、只读或只写(位或O_NONBLOCK)
a、open:以只写方式并位或O_NONBLOCK打开命名管道,且没有任何进程以读的方式打开命名管道,会失败(non_write_open.c)
b、open:以只读方式并位或O_NONBLOCK打开命名管道,会成功(non_read_open.c)
c、write和read是非阻塞的
d、读进程退出后,写进程再向命名管道中写数据,写进程也会退出(non_read_open.c non_write_open.c)