1、首先,进程的即是指程序执行的实例,它是运行中的程序。进程的状态包括三种:执行、就绪和阻塞状态。
执行状态的进程占用着CPU,而就绪状态的进程则是在等待分配CPU,最后的阻塞状态就是更低一级的状态,它等待着进入就绪状态。
进程和文件类似,每一个打开的进程都有它自己的ID(PID),可以使用ps 命令来查看它的ID,常用的有 “ps -ef”命令。当然一次显示的进程太多你也可以通过管道抓取一部分,比如:ps -ef | grep a.out 。通常和PID相伴随的还有PPID,该进程的父进程ID,即创建它的进程的ID。这样,我们就可以联想到进程的家族体系,最终会有一个祖先进程,它的名字为:init,我们可以通过查看ID号来证实,它的ID为1。 我们也可以使用另外一条命令:pstree来查看进程的树状图,比较直观。
2、进程有这样一些特点,动态产生动态消亡;可以并发执行;是能独立运行的基本单位;具有执行的间断性。
3、进程间是互斥的,若有若干进程需要使用同一共享资源时,任何时候都只允许一个进程使用,其它进程必须等待。这样的共享资源我们称之为临界资源,
4、一组并发进程按一定的顺序执行的过程称为进程间的同步。具有同步关系的一组并发进程称为合作进程,合作进程间互相发送的信号称为消息或事件。
5、关于进程的调度有很多调度算法,包括最短作业优先调度,基于优先级调度,先来先服务调度以及循环调度等。不同的调度方式能满足不同的用户需求。
6、最后就是关于进程死锁的问题,这是一种由多个进程因竞争资源而形成一种僵局,若无外力作用,这些进程都将永远不能再向前推进。
比如这样两个进程,A进程需要使用资源a,它先占用了资源a,并将它上锁,B进程占用了资源b也将b上锁,这时,A需要使用b,而B需要使用a,但双方进程没有结束前是不会将各自上锁的资源解锁的,这时就导致了进程死锁,形成了一种没有外力作用无法再向前推进的僵局。
由于上一篇介绍过fork() 函数的部分用法,接下来,就介绍一下exec 函数族:
1、execl :它的主要作用是,产生一个新的程序来替换原程序(注意是替换,并没有新建),它的参数可以有很多,主要的有:
参数1:路径,一个能找到该文件的路径;参数2:包含很多,用来表明执行方式,每一个参数都有各自的" ";参数n:NULL;
比如这样一个实例:execl ("/bin/ls", "ls", "-l", NULL); 这个函数就调用了/bin 目录下的 ls 函数。
当然,我们也可以用来做一些"无聊"的事情,比如在A程序中打印一行字再execl 一个B程序,而B程序的作用是打印一行字,再execl A程序,就形成了一个无限互相调用的死循环。
2、execlp:这个函数只是上一个execl的偷懒版本,当所需函数是PATH中的函数,就可以直接写函数名而不必写全路径。(PATH是环境变量,"echo $PATH"命令可以查看)
3、execlv:该函数也是同execl用法类似,只是它的参数除了参数1都可以放到一个字符串数组中,比如:char *str[ ] = {"ls", NULL} ,通过调用该字符串数组作为参数即可。