Linux系统编程(1)

1. 程序和进程、并行和并发

并发:指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

并行:多个处理机同时进行处理。

上图为3个进程轮流被cpu处理,每次处理一个时间碎片的时间。

2. PCB(进程控制块)

我们知道,每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体。

/usr/src/linux-headers-3.16.0-30/include/linux/sched.h文件中可以查看struct task_struct 结构体定义。其内部成员有很多,我们重点掌握以下部分即可:

* 进程id。系统中每个进程有唯一的id,在C语言中用pid_t类型表示,其实就是一个非负整数。

* 进程的状态,有就绪、运行、挂起、停止等状态。

* 进程切换时需要保存和恢复的一些CPU寄存器。

* 描述虚拟地址空间的信息。

* 描述控制终端的信息。

* 当前工作目录(Current Working Directory)。

* umask掩码。

* 文件描述符表,包含很多指向file结构体的指针。

* 和信号相关的信息。

* 用户id和组id。

* 会话(Session)和进程组。(父进程、子进程和兄弟进程在同一个进程组中,多个进程组组成一个会话)

* 进程可以使用的资源上限(Resource Limit)。

3. 进程状态的切换

4. fork函数

例:

5. 进程相关的问题分析

例:

执行结果:

多次反复执行,有时会得到如下结果:

这是因为:

6. 循环创建多个子进程

如果是下面这种方式创建多个子进程,那么会创建出多个不需要的进程:

所以要判断fork函数的返回值,当返回值为0时,说明当前是子进程,就不要再创建进程了,所以break。

当 i 等于0~4时,当前进程为子进程,当 i 等于5时,当前进程为父进程。

7. 进程间的数据共享

8. exec函数族功能介绍

9. exec函数族函数的使用

(1)使用execl函数,让子进程执行ls命令。

执行结果:

可以看到:++++++++++ i 这里的for循环只输出了一次,这是父进程输出的,子进程并没有输出。这是由于execl函数执行后,子进程的代码段就被替换为ls的代码了,所以执行ls输出后,子进程就结束了。

(2)使用execl函数,让子进程执行自己写的程序

执行结果:

(3)使用execlp函数,让子进程执行PATH环境变量能够搜索到的程序

(4)exec函数是有返回值的,但是没有用。因为如果execlp函数执行成功,那么子进程的代码段会被替换,所以后面的perror函数执行不到。而如果execlp函数执行失败,那么子进程的代码段没有被替换,那么后面的perror函数会输出错误信息,然后exit函数退出当前进程。代码如下:

10. 孤儿进程和僵尸进程

(1)孤儿进程例子:

执行结果:

可以看到子进程被1492号进程(ubuntu下的init进程)领养了。

(2)僵尸进程例子:

该例子中父进程一直进行while循环,没有回收子进程,所以此时子进程成为僵尸进程。ps aux一下也可以看到:

40763号进程为父进程,还在进行while循环,40764号为僵尸进程。

如果想让僵尸进程消失,用kill直接杀它是不行的,因为它已经死了。我们可以将该僵尸进程的父进程用kill命令杀死,那么僵尸进程就会被init进程领养,然后init进程会释放僵尸进程的pcb,然后就会看到父进程和僵尸进程都不存在了。

11. wait函数回收子进程资源

例1:父进程等待子进程正常退出后,回收子进程。

执行结果:

例2:父进程等待子进程正常退出后,回收子进程,并打印子进程的退出状态。

    

执行结果:

例3:父进程等待子进程被杀死后,回收子进程,并打印杀死子进程的信号的编号。

    

 

执行结果:

猜你喜欢

转载自blog.csdn.net/mengyujia1234/article/details/90763360