Linux通过 Task_struct 结构体来管理进程信息,包括进程的基本信息、内存信息、tty终端信息、当前目录信息,打开文件的描述符以及信号信息等。
进程状态包括就绪/运行状态、等待状态(可以被中断)、等待状态(不可以被中断)、停止状态和僵死状态。
创建进程
(1) fork()
无参数,失败返回值-1,成功则在父进程中返回子进程的PID号,在子进程中返回0
该函数成功后,子进程复制父进程几乎所有的信息(除PID信息),包括数据段、BSS段、代码段、堆空间、栈空间和文件描述符,而对于文件描述符关联的文件表项(具体文件),则采用共享的方式。
(2)vfork()
无需完全复制父进程的地址空间。如果派生的进程只执行exec()函数,则使用fork()从父进程复制到子进程的数据空间将不被使用,因此vfork的效率一般要比fork的效率要高。vfork只是在需要时复制,一般采用与父进程共享所有资源的方式处理。
(3)exec系列函数
在子进程中调用exec系列函数,该进程的代码段、数据段内容完全由新程序替代。注意:exec并不创建新的进程,所以前后进程号等信息并不发生变化,exec只是用新的程序替换当前进程的正文、数据、堆和栈段。
注意以下函数的区别:
#include <unistd.h>
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[]);
int execve(const char *path, char *const argv[], char *const envp[]);
(4)system()
system以新进程的方式运行一个程序,然后结束。system函数用来创建新的进程,并在此进程中运行新的进程,直到新的进程结束,才继续运行父进程。子进程结束后会返回退出状态。