您好,欢迎访问三七文档
进程控制进程控制理论基础进程控制编程定义进程是一个具有一定独立功能的程序的一次运行活动。特点动态性并发性独立性异步性状态进程ID进程ID(PID):标识进程的唯一数字父进程的ID(PPID)启动进程的用户ID(UID)进程互斥进程互斥是指当有若干进程都要使用某一共享资源时,任何时刻最多允许一个进程使用,其他要使用该资源的进程必须等待,直到占用该资源者释放了该资源为止。临界资源操作系统中将一次只允许一个进程访问的资源称为临界资源。临界区进程中访问临界资源的那段程序代码称为临界区。为实现对临界资源的互斥访问,应保证诸进程互斥地进入各自的临界区。进程同步一组并发进程按一定的顺序执行的过程称为进程间的同步。具有同步关系的一组并发进程称为合作进程,合作进程间互相发送的信号称为消息或事件。进程调度概念:按一定算法,从一组待运行的进程中选出一个来占有CPU运行。调度方式:抢占式非抢占式调度算法先来先服务调度算法短进程优先调度算法高优先级优先调度算法时间片轮转法死锁多个进程因竞争资源而形成一种僵局,若无外力作用,这些进程都将永远不能再向前推进。获取ID#includesys/types.h#includeunistd.hpid_tgetpid(void)获取本进程ID。pid_tgetppid(void)获取父进程ID。获取ID#includestdio.h#includeunistd.h#includestdlib.hintmain(void){printf(PID=%d\n,getpid());printf(PPID=%d\n,getppid());return0;}进程创建#includeunistd.hpid_tfork(void)功能:创建子进程fork的奇妙之处在于它被调用一次,却返回两次,它可能有三种不同的返回值:1.在父进程中,fork返回新创建的子进程的PID;2.在子进程中,fork返回0;3.如果出现错误,fork返回一个负值进程创建#includesys/types.h#inlcudeunistd.hmain(){pid_tpid;/*此时仅有一个进程*/pid=fork();/*此时已经有两个进程在同时运行*/if(pid0)printf(errorinfork!);elseif(pid==0)printf(Iamthechildprocess,IDis%d\n,getpid());elseprintf(Iamtheparentprocess,IDis%d\n,getpid());}?执行后的结果?进程创建$./fork_testIamtheparentprocess,myprocessIDis1991Iamthechildprocess,myprocessIDis1992在pid=fork()之前,只有一个进程在执行,但在这条语句执行之后,就变成两个进程在执行了,这两个进程的代码部分完全相同,将要执行的下一条语句都是f(pid==0)。两个进程中,原先就存在的那个进程被称作“父进程”,新出现的那个进程被称作“子进程”,父子进程的区别在于进程标识符(PID)不同。进程创建—思考运行结果?#includeunistd.h#includestdio.hintmain(void){pid_tpid;intcount=0;count++;pid=fork();printf(Thisisfirsttime,pid=%d\n,pid);printf(Thisissecondtime,pid=%d\n,pid);count++;printf(count=%d\n,count);if(pid0)printf(Thisisparentprocess,thechildhasthepid:%d\n,pid);elseif(!pid)printf(Thisisthechildprocess.\n);elseprintf(forkfailed.\n);printf(Thisisthirdtime,pid=%d\n,pid);printf(Thisisfouthtime,pid=%d\n,pid);return0;}进程创建—思考运行结果?父进程的数据空间、堆栈空间都会给子进程一个拷贝,而不是共享这些内存。在子进程中对count进行自加1的操作,但是并没有影响到父进程中的count值,父进程中的count值仍然为0。进程创建#includesys/types.h#includeunistd.hpid_tvfork(void)功能:创建子进程。创建进程区别:1.fork要拷贝父进程的数据段;而vfork则不需要完全拷贝父进程的数据段,子进程与父进程共享数据段。2.fork不对父子进程的执行次序进行任何限制;而在vfork调用中,子进程先运行,父进程挂起。进程创建1.#includesys/types.h2.#includesys/stat.h3.#includeunistd.h4.main(){5.intcount=1;6.intchild;7.8.printf(“Beforecreateson,thefather‘scountis:%d\n”,count);9.if(!(child=vfork()))10.{11.printf(Thisisson,hispidis:%dandthecountis:%d\n,getpid(),++count);12.exit(1);13.}else{14.printf(Afterson,Thisisfather,hispidis:%dandthecountis:%d,andthechildis:%d\n,getpid(),count,child);15.}16.}执行程序exec用被执行的程序替换调用它的程序。区别:fork创建一个新的进程,产生一个新的PID。exec启动一个新程序,替换原有的进程,因此进程的PID不会改变,和调用exec函数的进程一样。执行程序#includeunistd.hintexecl(constchar*path,constchar*arg,....)功能:运行参数path所指定的可执行文件,接下来的参数代表执行该文件时传递过去的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。执行程序#includeunistd.hmain(){execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char*)0);}执行程序#includeunistd.hintexeclp(constchar*file,constchar*arg,……)功能:从PATH环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。执行程序#includeunistd.hmain(){execlp(”ls”,”ls”,”-al”,”/etc/passwd”,(char*)0);}执行程序#includeunistd.hintexecv(constchar*path,char*constargv[])功能:执行参数path所指定的文件,与execl()不同的地方在于execve()只需两个参数,第二个参数利用数组指针来传递给执行文件。执行程序#includeunistd.hmain(){char*argv[]={“ls”,”-al”,”/etc/passwd”,(char*)0};execv(“/bin/ls”,argv);}执行程序#includestdlib.hintsystem(constchar*string)功能:调用fork()产生子进程,由子进程来调用/bin/sh-cstring来执行参数string字符串所代表的命令。执行程序#includestdlib.hmain(){system(“ls-al/etc/passwd/etc/shadow”);}等待#includesys/types.h#includesys/wait.hpid_twait(int*status)功能:进程一旦调用了wait,就立即阻塞自己,直到自己的某个子进程退出,如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。等待#includesys/types.h#includesys/wait.h#includeunistd.h#includestdlib.hmain(){pid_tpc,pr;pc=fork();if(pc0)/*如果出错*/printf(errorocurred!\n);elseif(pc==0){/*如果是子进程*/printf(Thisischildprocesswithpidof%d\n,getpid());sleep(10);/*睡眠10秒钟*/}else{/*如果是父进程*/pr=wait(NULL);/*在这里等待*/printf(Icatchedachildprocesswithpidof%d\n),pr);}exit(0);}等待#includesys/types.h#includesys/wait.hpid_twaitpid(pid_tpid,int*status,intoptions)功能:进程一旦调用了wait,就立即阻塞自己,直到自己的某个子进程退出,如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。等待当pid取不同的值时,有不同的意义:1.pid0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。2.pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。3.pid=0时,等待同一个进程组中的任何子进程。4.pid-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。等待参数option可以为0或下面的OR组合:WNOHANG:如果没有任何已经结束的子进程则马上返回,不予以等待。WUNTRACED:如果子进程进入暂停执行情况则马上返回。发送信号#includesys/types.h#includesignal.hintkill(pid_tpid,intsig)功能:发送参数sig指定的信号给参数pid指定的进程pid0将信号传给进程识别码为pid的进程pid=0将信号传给和目前进程相同进程组的所有进程pid=-1将信号广播传送给系统内所有的进程pid0将信号传给进程组识别码为pid绝对值的所有进程退出exit和_exit用于中止进程:_exit的作用:直接使进程停止运行,清除其使用的内存空间,并清除其在内核中的数据结构。exit与_exit函数不同,使进程停止运行之前要检查文件打开情况,并把文件缓冲区的内容写回文件中去之后才停止进程。
本文标题:进程控制
链接地址:https://www.777doc.com/doc-3837224 .html