linux多进程,文件描述符

文件

一般CPU都是以"页"为单位来分配内存空间的,每一个页都是实际物理内存的一个映像,像INTEL的CPU,其一页在通常情况下是4086字节大小,而无论是数据段还是堆栈段都是由许多"页"构成的,fork函数复制这两个段,只是"逻辑"上的,并非"物理"上的,也就是说,实际执行fork时,物理空间上两个进程的数据段和堆栈段都还是共享着的,当有一个进程写了某个数据时,这时两个进程之间的数据才有了区别,系统就将有区别的"页"从物理上也分开。系统在空间上的开销就可以达到最小

多进程中,每个进程维护一个文件描述表,指向系统维护的打开文件表,而打开文件表指向文件系统i-node表。打开文件表项记录着文件的读写位置。一般情况下,open操作新建一个文件描述表项和对应的打开文件表项。
特殊情况:

  • 同一进程打开同一文件两次,也会新建两个描述符和两个打开文件表项目。
  • 使用dup函数时,会新建描述符并指向旧的打开文件表项,并使打开文件表项的引用次数加1
  • 子进程会复制父进程的描述表,fork之后父子进程分别open,和多进程一般情况一样。
  • fork之前open, 各自的描述项指向同一打开文件表项,文件表项的引用次数加1
    需要注意的是:如果想要释放这个打开文件表项,也必须父子进程都close一次描述表项才会释放,如果不close,进程退出的时候会自动close掉所有的文件描述符。
    linux多进程,文件描述符

管道

基本用法:

  1. 这对套接字可以用于全双工通信,每一个套接字既可以读也可以写。例如,可以往sv[0]中写,从sv[1]中读;或者从sv[1]中写,从sv[0]中读;
  2. 如果往一个套接字(如sv[0])中写入后,再从该套接字读时会阻塞,只能在另一个套接字中(sv[1])上读成功;
  3. 读、写操作可以位于同一个进程,也可以分别位于不同的进程,如父子进程。如果是父子进程时,一般会功能分离,一个进程用来读,一个用来写。因为文件描述副sv[0]和sv[1]是进程共享的,所以读的进程要关闭写描述符, 反之,写的进程关闭读描述符。
    举例: