- 程序和进程
- 产生进程
- 销毁进程
我们经常谈论程序,实际上就是一堆指令和数据的集合,这个集合反映在了一个静态可执行文件和相关的配置文件等,而进程是什么呢?
操作系统可以运行多个程序,那他是如何运行的?实际上,CPU的执行是很快的,而待运行的程序很多,那么为了让操作系统运行多个程序,CPU会把它的执行时间划分成很多段,比如每一段是0.1秒,那么就可以这样A程序运行0.1秒,然后B程序运行0.1,然后C程序运行0.2秒,因为这个切换很快,所以我们感觉程序是同时运行的。
从操作系统上看上面提到的运行程序就是指一个进程,因为存在切换,所以进程管理了很多资源(如打开的文件、挂起的信号、进程状态、内存地址空间等等),也就是说进程参与了CPU的调度,和管理了所有资源,哦,这句话,不是很正确,实际上现代CPU的执行非常非常快,而且操作系统有多个CPU,使用一个进程参与调度时,频繁地从CPU的寄存器和进程堆栈的保存运行状态和对应的信息都很耗时,所以现代CPU将进程仅仅作为一个资源管理的东东,而引入了线程作为CPU调度的基本单位,多个线程可以共享同一进程的所有资源(后面会讲线程)。
注意,程序并不是进程,实际上两个或多个进程不仅有可能执行同一程序,而且还有可能共享地址空间等资源。 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息。它定义在include/linux/sched.h文件中。
创建进程很简单,直接调用fork函数:
#include
pid_t fork(void);
创建进程用法举例:
#include#include int main(){ pid_t fpid;//fpid表示fork函数返回的值 int count=0; fpid=fork(); if (fpid < 0) printf("error in fork!"); else if (fpid == 0) { printf("i am the child process, my process id is %dn",getpid()); printf("I’m childrenn"); count +=2; }else { printf("i am the parent process, my process id is %d/n",getpid()); printf("I’m parent.n"); count++; } printf("统计结果是: %d/n",count); return 0; }
调用fork函数后,会创建一个子进程,并且父子两个进程都从fork处执行,fork函数有两个返回值,对于父进程会返回子进程的pid,此时pid会大于0,对于子进程来说,pid会等于0。
但是,我们上一节说过进程是内核调度资源的基本单位,那父子进程管理的资源有什么关系呢? 传统的linux操作系统以统一的方式对待所有的进程:子进程复制父进程所拥有的所有资源,这种方法使得创建进程非常非常非常慢,因为子进程需要拷贝父进程的所有的地址空间,那现代的操作系统,是如何处理的呢?主要有以下三种方式:
• 写时复制
• 轻量级进程允许父子进程共享每进程在内核的很多数据结构,比如地址空间、打开文件表和信号处理。
• vfork系统调用创建的进程能共享其父进程的内存地址空间,为了防止父进程重写子进程需要的数据,阻塞父进程的执行,一直到子进程退出为止。
exit - 终止正在执行的进程
#include
void exit(int status);
DEscriptION
The exit() function causes normal process termination and the value of status & 0377 is returned to the parent (see wait(2)).
#include#include #include #include #include int main(){ pid_t fpid;//fpid表示fork函数返回的值 int count=0; int status = 0; fpid=fork(); if (fpid < 0) printf("error in fork!n"); else if (fpid == 0) { printf("i am the child process, my process id is %dn",getpid()); printf("I’m childrenn"); count +=2; exit(-10); }else { printf("i am the parent process, my process id is %dn",getpid()); printf("I’m parent.n"); count++; } printf("统计结果是: %dn",count); //父进程捕捉子进程的状态 wait(&status); printf("parent: status: %dn", WEXITSTATUS(status)); return 0; }



