目录
一、什么是进程
- 进程是程序执行的动态过程
- 进程是资源管理的最小单位(线程是系统调度的最小单位)
- 在linux中,我们可以通过 file 文件名 得知一个文件的文件类型,以一个可执行程序为例,如下图所示
- 由上面可以得知,大多数的可执行程序的格式为ELF格式。那么一个可执行程序,是如何被linux运行起来的呢?如下图所示
当ELF格式的可执行程序被执行的时候,程序被加载到内存中执行,此时内核产生了一个名为task_struct{}的结构体来表示与管理这个进程。
其中:
- .text 段存放代码,只读并且共享,这段内存在程序运行期间不会被释放
- .data段存放已经初始化的全局变量和已经初始化的static变量,可读可写,这段内存在程序运行期间一直存在。
- .bss段存放未初始化的全局变量和未初始化的static变量,可读可写,这段内存在程序运行期间一直存在。
- .rodata段存放只读数据(如:字符串常量)
二、进程的“生老病死”
- 进程从“诞生”到“被回收”的一系列过程状态转换图,如下图所示
一般流程为:
- 父进程调用fork函数,生成子进程(使用fork产生的子进程与父进程一模一样,并且子进程会从fork返回值后的下一条逻辑语句开始执行)
- 子进程运行结束,执行exit退出
- 父进程使用wait或者waitpid回收子进程的资源
三、进程相关函数
1、子进程的创建
- pid_t fork(void);
2、进程的退出
- void exit(int status);//清空I/O缓冲区之后,才退出进程 ,在多进程里面,进程正常退出需要用exit(0)
- void _exit(int status);//直接结束进程,不做清理的操作,直接进入到内核。
- return 0;// return是c语言里面的一个关键字。如果是在调用函数的时候,是出栈的处理。如果是在main函数里面,是结束进程
3、子进程资源的回收(如果子进程资源没有被回收,则会变成僵尸进程,占用系统资源)
- pid_t wait(int *stat_loc);//阻塞
- pid_t waitpid(pid_t pid, int *stat_loc, int options);//可阻塞 或者 无阻塞
4、在一个进程中调用另外一个进程(system调用其他进程是通过shell调用其他进程,本程序进程与被调用的进程之间没有关系。)
- int system(const char *command);
- 如:system("ls -l")、system("./main")
5、子进程中运行其他程序(程序的替换,覆盖原有代码)
其中:execl 中的l 与execv 中的v 的含义
l: list 列表,把参数一一列表写在参数里面,写完之后,需要加一个NULL。
v: vector 向量、数组,把参数写进去。
- int execl(const char *path, const char *arg, ... , /* (char *) NULL */);
- int execlp(const char *file, const char *arg, ... , /* (char *) NULL */);
- int execle(const char *path, const char *arg, ... , /*, (char *) NULL, char * const envp[] */);
- int execv(const char *path, char *const argv[]);
- int execvp(const char *file, char *const argv[]);
- int execvpe(const char *file, char *const argv[], char *const envp[]);