第十章 进程与僵尸进程 (上)

来源:互联网 发布:翼龙贷网网络贷款 编辑:程序博客网 时间:2024/06/15 14:48

《TCP/IP网络编程》 尹圣雨

P155~


并发服务器端的实现方法

网络程序中数据通信时间比CPU运算时间占比更大,因此向多个客户端提供服务是一种有效利用CPU的方式。


具有代表性的并发服务器端实现模型与方法:

多进程服务器:通过创建多个进程提供服务。 (不适合window平台,主要放在Linux平台)

多路复用服务器:提供捆绑并统一管理I/O对象提供服务。

多线程服务器:提供生成与客户端等量的线程提供服务。


进程-占用内存空间的正在运行的程序。从操作系统看,进程是程序流的基本单位,若创建多个进程,则操作系统将同时运行。有时一个程序运行过程中也会产生多个进程。


注意:1个CPU可能包含多个运算设备(核),核的个数与可同时运行的进程数相同。相反,若进程数超过核数,进程将分时使用CPU资源。但因为CPU运转速度快,我们感受到所有进程同时运行。


无论进程是如何创建的,所有进程都会从操作系统分配到ID。此ID称为“进程ID”,其值为大于2的整数。1要分配给操作系统启动后的首个进程,因此用户进程无法得到ID的值1.


通过调用fork函数创建进程

#include<unisd.h>pid_t fork(void);       //成功时返回进程ID,失败时返回-1

fork函数将创建调用的进程副本。并非根据完全不同的程序创建进程,而是复制正在运行的、调用fork函数的进程。另外,两个进程都将执行fork函数调用后的语句(在fork函数调用之后)。但因为通过同一个进程、复制相同的内存空间,之后的程序流要根据fork函数的返回值加以区分。即利用fork函数的如下特点区分程序执行流程。

父进程:fork函数返回子进程ID。

子进程:fork函数返回0.

"父进程"指原进程,即调用fork函数的主体,而“子进程”是通过父进程调用fork函数复制出的进程。fork函数后分成了两个完全不同的进程,只是二者共享同一个代码而已。


P159~

僵尸Zombie进程

进程完成工作后(执行完main函数之后的程序后)应被销毁,但有时这些进程会变成僵尸进程,占用系统之后的内重要资源。


僵尸进程产生原因:传递参数并调用exit函数、main函数中执行return语句并返回值。

向exit函数传递的参数值和main函数的return语句返回的值都会传递给操作系统。而操作系统不会销毁子进程,直到把这些值传递给产生该子进程的父进程。处在这种状态下的进程就是僵尸进程。


将子进程变成僵尸进程的正是操作系统,僵尸进程何时被销毁? 应该向创建子进程的父进程传递子进程的exit函数值或return语句的返回值。

如何向父进程传递这些值?必须父进程主动发起请求(函数调用)时,操作系统才会传递该值。


后台处理 Background Processing:将控制台窗口中的指令放到后台运行的方式。

销毁僵尸进程:1、利用wait函数,成功时返回终止的子进程ID,失败时返回-1.

#include<sys/wait.h>pid_t wait(int * statloc);

调用此函数时如果已有子进程终止,那么此进程终止时传递的返回值将保存到该函数的参数所指内存空间。但函数参数指向的单元中还包含其他信息,因此需要通过下列宏进行分离。

WIFEXITED 子进程正常终止时返回“真”。

WEXITSTATUS返回子进程的返回值。


调用wait函数时,如果没有已终止的子进程,那么程序将阻塞直到有子进程终止,因此需要谨慎调用该函数。


销毁僵尸进程:2、利用waitpid函数(可以防止阻塞)

#include<sys/wait.h>pid_t waitpid(pid_t pid, int * statloc, int options);//成功时返回终止的子进程ID(或0),失败时返回-1

pid:等待终止的目标子进程的ID,若传递为-1,则与wait函数相同,可以等待任意子进程终止。

statloc:与wait函数的statloc参数具有相同含义。

options:传递头文件sys/wait.h中声明的常量WNOHANG,即使没有终止的子进程也不会进入阻塞状态,而是返回0并退出函数。





原创粉丝点击