linux系统编程之进程

一、进程基础 每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息:

* 进程id。系统中每个进程有唯一的id,其本质就是一个非负整数。

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

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

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

* 描述控制终端的信息。

* 当前工作目录。

* umask掩码。

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

* 和信号相关的信息。

用户id和组id。

* 控制终端、Session和进程组。

* 进程可以使用的资源上限。

二、进程环境

libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文中,所以在使用时要用extern声明。环境变量定义了进程的运行环境,一些比较重要的环境变量的含义如下:

PATH:可执行文件的搜索路径。 SHELL:当前shell。 TERM:当前终端类型。 LANG:语言和locale,决定了字符编码以及时间、货币等信息的显示格式。 HOME:当前用户主目录的路径,很多程序需要在主目录下保存配置文件,使得每 个用户在运行该程序时都有自己的一套配置。

打印当前环境变量的值:

#include

int main(void)

{

extern char **environ;

int i;

for(i=0; environ[i]!=NULL; i++)

printf("%s\n", environ[i]);

return 0;

}

三、进程控制原语  

1.fork函数  

头文件 include  

函数原型 pid_t fork(void);  

子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同。fork调用一次返回两次。父进程中返回子进程ID, 子进程中返回0 。遵循读时共享,写时复制原则。  

父子进程共享:(1)文件描述符指向的结构体 (2)mmap建立的映射区  

2.相关函数  

include include  

pid_t getpid(void); //返回调用进程的PID号  

pid_t getppid(void); //返回调用进程父进程的PID号  

3.exec函数族 include

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg, ..., char *const envp[]);

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]); 

这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回,如果调用出错则返回-1,所以exec函数只有出错的返回值而没有成功的返回值。  

4.wait/waitpid

僵尸进程: 子进程退出,父进程没有回收子进程资源(PCB),则子进程变成僵尸进程孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为1号进程init进程,称为init进程领养孤儿进程。

wait函数有三个功能:(1)阻塞等待子进程退出(2)回收子进程残留的pcb资源(3)用wait函数的传出参数status来保存进程退出状态,判断进程终止原因

waitpid函数可以回收指定的子进程一次wait或waitpid调用只能清理一个子进程,清理多个子进程应用循环

include

include

pid_t wait(int *status);

pid_t waitpid(pid_t pid, int *status, int options);

< -1 回收指定进程组内的任意子进程

-1 回收任意子进程

0 回收和当前调用waitpid一个组的所有子进程

> 0 回收指定ID的子进程

你可能感兴趣的:(linux系统编程之进程)