Bootstrap

Linux系统编程(2)

1. 父子进程使用文件进行通信

先打开一个文件,然后fork出子进程,父进程和子进程都拥有这个文件描述符。父进程向该文件中写一句话,然后关闭文件描述符。然后过了一秒后子进程醒了,子进程先把文件指针移到文件的初始位置,然后读文件并打印输出,最后关闭文件描述符。

示意图:

执行结果:

2. 父进程fork三个子进程例子

段错误:

 

执行结果:

解释:前两个子进程是正常退出的,最后一个子进程是发生了段错误,于是系统会向该子进程发信号11杀死该子进程。所以结果如上图。

3. waitpid函数

        

注:如果子进程被创建出来之后,通过某种操作被送到了其他进程组中,那么该子进程就不和父进程在同一个进程组了,参数需要用pid<0,将该子进程的pid加个负号。(pid参数大于0和等于-1的这两种比较常用)

例:pid参数为-1,非阻塞。

 

解释:当wpid等于0时,说明子进程处于运行状态,那么continue。

4. ipc的概念

5. 管道相关的概念

 

6. pipe函数的使用

返回值:成功为0,失败为-1。

例:

执行结果:

7. 有血缘关系的进程间通信fork的位置

fork位置应该在创建管道之后,这样父进程和子进程就都使用同一个管道。

8. 使用匹配父子进程间通信练习思路

ps aux默认是写到终端的,所以我们需要用dup2,这样在文件描述符重定向之后,ps aux就会写到管道的“写”端了。同理,grep bash默认是从终端读的,所以我们需要用dup2,这样在文件描述符重定向之后,grep bash就会从管道的“读”端去读了。

管道的内部实现是队列,所以数据只能读一次。当子进程往管道中写数据时,为了防止父进程也读、子进程也读的情况,要在子进程中关闭管道的读端,这样就只是子进程在写,父进程在读了;当父进程从管道中读数据时,为了防止父进程也写,子进程也写的情况,要在父进程中关闭管道的写端,这样就只是子进程在写,父进程在读了。

9. 父子进程通信代码实现 ps aux | grep bash

       

 

执行结果:

注:1. 上面是父进程写,子进程读。如果我们还需要进行父进程读,子进程写的话,那么我们就需要再创建一根管道。

       2. 如果写操作的进程不关闭读端,读操作的进程不关闭写端,那么会造成阻塞,grep读不到数据一直在那里等,如下:

10. 兄弟进程间通信

父进程中需要关闭管道的读写两端。子进程1中需要关闭管道的读端,子进程2中需要关闭管道的写端。

例:

 

  

  

执行结果:

11. 管道的读写行为

12. 验证管道缓冲区大小

例:

执行结果:

13. 设置管道的非阻塞属性

上面的三行紫色代码即可完成设置管道的非阻塞属性。

14. fifo的创建

fifo文件大小为0,里面不存数据,数据存在内核的缓冲区里面。只要有fifo文件,就会和内核缓冲区做一个映射,这是操作系统行为。

其中pathname是fifo文件的名字,mode是设置文件权限的参数。最终真正的权限是我们设置的参数再与umask取反的按位与:

15. fifo进行没有血缘关系的进程间通信

先创建fifo文件,名字是myfifo,然后执行a.c的进程和执行b.c的进程之间进行通信:

管道默认有阻塞属性,所以当写进程还没有写数据时,读进程会阻塞在那里等待。当管道中有数据了之后,读进程就开始读。

16. mmap函数参数讲解

(1)mmap函数

   

           

  

注:映射区的大小为4k的整数倍,所以如果参数设置为100字节,会发现映射区大小为4k。

(2)munmap函数

17. 使用mmap读取磁盘文件内容

 

;