1.什么是进程
遇到这样的问题我就头疼,感觉这样问题太笼统了,我回答不好。现在有几个有名关于进程的定义:
(1)进程是独立的可调度的活动
(2)进程是一个抽象实体,当它执行某个任务时,要分配和释放各种资源
(3)进程是并行执行的单位
总结------进程就是程序的动态执行过程,包括创建,调度,消亡过程,它是程序执行,资源分配的最小单位。在linux键入命令执行一个程序是就启动了一个进程
2.进程控制块
进程控制块包含了进程的描述信息,控制信息,资源信息,它是进程的一个静态描述
3.进程标示
pid------当前进程的标示,通过getpid()获得
ppid-----当前进程的父进程的标示,通过getppid()获得
ps:进程的标示除了进程的id,还有用户,用户组标示,进程时间,资源利用情况等
4.进程的运行状态
进程既然是程序的执行过程,那么它就有各种状态,它有执行态,就绪态,等待态
执行态-------进程正在执行,正在占用cpu
就绪态-------具有一切执行的条件,等待cpu分配时间片段
等待态--------进程不能使用cpu,可能是由于某些资源没有分配,等分配好了可以将其唤醒到就绪态 三者具体关系如下:
5.linux下进程的结构
linux是一个多用户多任务的操作系统,每个进程都在各自的虚拟空间上运行,一个进程挂了也不会影响到其他的进程,linux包括三个段“数据段”,“代码段”, “堆栈段”
数据段:包括全局变量,常数,动态分配的空间,包括普通数据段,BBS数据段,堆
普通数据段-------包括可读可写/只读数据段,存放静态初始化的全局变量,常量
BBS数据段-------存放未初始化的全局变量
堆-------------------存放动态分配的空间,数据结构中的堆是一种二叉树
代码段:存放程序代码的数据
堆栈段:存放子程序的返回地址,子程序的参数,程序的局部变量等
*****************************************************************
一个有趣的程序
这段程序的输出是:
我感到非常奇怪,对于if...else这样一种选择怎么会输出两种结果呢?下面解释一下fork函数
fork()---------在父进程中创建子进程,子进程是父进程的一个复制品,它会从父进程继承整个地址空间,包括进程上下文,代码段,堆栈,内存信息......子进程不同的是它的进程号,资源使用和计时器等。fork()会返回两个值,在父进程中返回的是子进程的ID,在子进程中返回的是0,在执行fork函数后,父子进程会在不同的地址空间运行同一段程序,就是它们都会执行下面的选择语句,只是父进程在大于0里面,子进程在等于0里面,所以可以在等于0的循环里面做一些子进程可以做的事情,就是这个样子的。
ps:因为fork一次会创建一个进程,所以在if..else不能多次使用fork()函数,fork函数的代价很大,所以出现了vfork(),但不产生父进程的副本,它通过允许父子进程可以访问相同的物理内存从而伪装了对进程地址空间的真实拷贝,当子进程需要改变内存中的数据时才复制,这就是著名的“写操作时复制”,现在许多嵌入式系统中的fork()函数是用vfork()实现的。
6.两个函数的使用wait(),waitpid()
wait()-------------该函数会使父进程阻塞,直到一个子进程结束,或者进程接收到了指定的信号,如果没有子进程或它的子进程已经结束,则wait()会立即返回
waitpid()---------它的作用和wait()差不多,但它并不一定等待第一个终止的子进程,它还有其他的选项,如提供非阻塞的wait(),,可以支持作业控制,所以wait()只是waitpid()的一个特例,linux内部是用waitpid()实现wait()的。
wait()的函数语法
waitpid()的函数语法
这里有使用waitpid()的例子
#include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { pid_t pc, pr ; pc = fork() ; if (pc < 0) { printf("fork erreor") ; } else if(pc == 0) { sleep(5) ; exit(0) ; } else { do{ pr = waitpid(pc, NULL, WNOHANG) ; if (pr == 0) { printf("the chile process has not exit!\n") ; sleep(1) ; } }while (pr == 0) ; if (pr == pc) { printf("get child exit code :%d\n", pr) ; } else { printf("some error ocdered\n") ; } } }
程序输出结果为:
看下这个程序waitpid(pc, NULL, WNOHANG),子进程暂停5秒,由于是WNOHANG参数所以不会阻塞,没有子进程返回时函数返回0,当有子进程返回时返回的时子进程的ID,父进程每1秒判断一次所以打印5次。
如果把pr = waitpid(pc, NULL, WNOHANG)换成pr = wait(NULL)或者waitpid(pc, NULL, 0),因为这两种调用会阻塞父进程,所以结果为: