进程相关知识
1.进程的状态
进程最主要的状态有两种:运行状态和等待状态(也叫阻塞状态,挂起状态,睡眠状态)。
运行状态和等待状态的进程的最大区别是,系统总是按照优先级在分时处理运行状态的进程,而不顾那些处于等待状态的进程。使用者对进程状态的关心,主要关心进程在某段时间所处的状态使得进程会不会去抢夺cpu,尤其那些等待时间长度不定的状态。
处于运行状态的进程,会因为等待某些事件的发生而转为睡眠状态。处于睡眠状态的进程,在条件满足后,被唤醒,重新转为运行状态,被调度执行。
Unix或其他系统的内核,将可运行进程按优先级分成几个不同的队列,高优先级进程优先被调度执行。Unix中可以用nice()系统调用很有限度的调整进程的优先级,windows也有类似的调用。
作为一个程序员,需要了解的是进程进入等待状态的诱因是因为程序员在程序中直接或者间接的安排了某个系统调用。
2.进程执行的时间 :time,vmstat
使用time命令,可以打印出 程序执行所花费的时间。这三个值分别是:实际时间,系统时间和用户时间。
实际时间是进程从开始运行到停止所花费的真实时间。
系统时间是在进程运行期间,操作系统内核为进程的活动所花费的cpu时间。
用户时间是运行用户态程序所花费的cpu时间。
系统时间和用户时间之和不一定等于实际时间,一般来说会小于实际时间。因为进程在生命周期内可能会睡眠,不占cpu时间,或者,尽管程程在活动期间从不休眠,但是Unix是个分时系统,系统会轮流调度其他进程,这样进程也没有占用它生命期内100%的cpu时间。
例:使用time命令统计执行一个命令所占用的cpu时间。
/usr/bin/time find /usr -name '*.c' -print
与cpu时间有关的另一个命令vmstat,它可以打印出整个系统,包括所有进程,近期内占用cpu的情况。vmstat后跟一个表示数值的参数,如:vmstat 10,那么每10秒钟给出一个报告。
3.创建新进程 :fork
系统调用fork创建一个新进程,但新进程的指令段,用户数据段,用户堆栈段都是旧进程一模一样的复制。系统数据段几乎全是旧进程的复制。原先进程被称为“父进程”,新创建的进程被称为“子进程”。在Unix系统中,fork系统调用时创建新进程的唯一方式。fork调用出错的唯一方式是系统中的资源耗尽。
创建新的进程之后,子进程复制了父进程的页表,而不是复制父进程的内存空间。父子进程的页表都指向了相同的物理内存页面。
进程最主要的状态有两种:运行状态和等待状态(也叫阻塞状态,挂起状态,睡眠状态)。
运行状态和等待状态的进程的最大区别是,系统总是按照优先级在分时处理运行状态的进程,而不顾那些处于等待状态的进程。使用者对进程状态的关心,主要关心进程在某段时间所处的状态使得进程会不会去抢夺cpu,尤其那些等待时间长度不定的状态。
处于运行状态的进程,会因为等待某些事件的发生而转为睡眠状态。处于睡眠状态的进程,在条件满足后,被唤醒,重新转为运行状态,被调度执行。
Unix或其他系统的内核,将可运行进程按优先级分成几个不同的队列,高优先级进程优先被调度执行。Unix中可以用nice()系统调用很有限度的调整进程的优先级,windows也有类似的调用。
作为一个程序员,需要了解的是进程进入等待状态的诱因是因为程序员在程序中直接或者间接的安排了某个系统调用。
2.进程执行的时间 :time,vmstat
使用time命令,可以打印出 程序执行所花费的时间。这三个值分别是:实际时间,系统时间和用户时间。
实际时间是进程从开始运行到停止所花费的真实时间。
系统时间是在进程运行期间,操作系统内核为进程的活动所花费的cpu时间。
用户时间是运行用户态程序所花费的cpu时间。
系统时间和用户时间之和不一定等于实际时间,一般来说会小于实际时间。因为进程在生命周期内可能会睡眠,不占cpu时间,或者,尽管程程在活动期间从不休眠,但是Unix是个分时系统,系统会轮流调度其他进程,这样进程也没有占用它生命期内100%的cpu时间。
例:使用time命令统计执行一个命令所占用的cpu时间。
/usr/bin/time find /usr -name '*.c' -print
与cpu时间有关的另一个命令vmstat,它可以打印出整个系统,包括所有进程,近期内占用cpu的情况。vmstat后跟一个表示数值的参数,如:vmstat 10,那么每10秒钟给出一个报告。
3.创建新进程 :fork
系统调用fork创建一个新进程,但新进程的指令段,用户数据段,用户堆栈段都是旧进程一模一样的复制。系统数据段几乎全是旧进程的复制。原先进程被称为“父进程”,新创建的进程被称为“子进程”。在Unix系统中,fork系统调用时创建新进程的唯一方式。fork调用出错的唯一方式是系统中的资源耗尽。
创建新的进程之后,子进程复制了父进程的页表,而不是复制父进程的内存空间。父子进程的页表都指向了相同的物理内存页面。