您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > Linux系统编程(第五章) 进程
第五章:进程及相关目标:本章旨在向学员介绍Linux系统下进程的概念及相关的系统调用使用:1)掌握进程的特点及应用2)掌握进程相关的系统调用函数的使用时间:6学时教学方法:讲授PPT、实例练习5.1什么是进程?概念概念每个运行着的程序实例就构成一个进程,就好象linux系统下ls命令实现实现执行cata.txt|wc–l从操作上看是实现统计a.txt文本的行数的功能,从程序的角度,就是两个进程间通过管道进行通信的例子特点特点linux系统允许多用户访问系统,每个用户可以同时运行许多程序,或者同时运行同一个程序的许多个实例组成组成进程由程序代码、数据、变量、打开的文件和环境组成,linux系统会在进程之间共享程序代码和系统函数库5.1什么是进程?•两个用户同时调用grep命令的效果#greptroinextgen.doctrek.txtnextgen.docneil文件文件函数库函数库数据s=“kirk”代码PID101数据s=“troi”代码PID102grep程序代码C程序函数库#grepkirktrek.txtrick5.2进程•进程id每个进程都有唯一的进程ID号,通过进程ID可以查找到相应的进程及了解进程的当前状态#includesys/types.h#includeunistd.hpid_tgetpid(void);//返回进程IDpid_tgetppid(void);//返回父进程IDuid_tgetuid(void);//返回实用户IDuid_tgeteuid(void);//返回有效用户IDgid_tgetgid(void);//返回真实组IDgid_tgetegid(void);//返回有效组ID5.2进程编程•fork系统调用:功能为创建进程#includesys/types.h#includeunistd.hpid_tfork(void);fork()fork()最初的进程最初的进程原进程原进程继续执行继续执行新进程新进程返回新PID返回0#includeunistd.hpid_tpid;pid=fork();5.2进程编程实验:fork系统调用#includesys/types.h#includeunistd.h#includestdio.hintmain(){pid_tpid;char*message;intn;printf(“forkprogramstaring\n”);pid=fork();switch(pid){case-1:perror(“forkfailed”);exit(1);case0:message=“Thisisthechild”;n=5;break;default:message=“Thisistheparent”;n=3;break;}for(;n0;n--){puts(message);sleep(1);}exit(0);}5.2进程编程fork()与vfork()的区别:•vfork()使用中父子进程共享虚拟内存空间,fork()则不是•vfork保证子进程先运行,而fork的父子进程运行顺序是不定的,它取决于内核的调度算法5.2进程编程•实验:vfork()与fork()的区别1#includesys/types.h#includeunistd.h#includestdio.hintmain(){pid_tpid;pid=vfork();if(pid0)printf(“vforkfailed\n”)elseif(pid==0){sleep(1);prntf(“helloIamchild\n”);}elseprintf(“helloIamparent\n”);exit(0);}5.2进程编程•实验:vfork()与fork()的区别2#includesys/types.h#includeunistd.h#includestdio.hintmain(){inti=0;pid_tpid;pid=vfork();if(pid0)printf(“vforkfailed\n”)elseif(pid==0){sleep(1);i++;printf(“helloIamchild,%d\n”,i);}elseprintf(“helloIamparent,%d\n”,i);exit(0);}5.2进程编程•wait系统调用:功能为当子进程运行时,会挂起调用进程wait经常会在fork之后被父进程调用#includesys/types.h#includesys/wait.hpid_twait(int*stat_loc);WIFEXITED(stat_val)如果子进程正常结束,取非零值WEXITSTATUS(stat_val)如果WIFEXITED非零,返回子进程的退出码WIFSIGNALED(stat_val)如果子进程因为一个未捕获的信号终止,取非零值WTERMSIG(stat_val)如果WIFSIGNALED非零,返回一个信号代码WIFSTOPPED(stat_val)如果子进程意外终止,取一个非零值WSTOPSIG(stat_val)如果WIFSTOPPED非零,返回一个信号代码5.2进程编程•例程:wait系统调用1#includesys/wait.hintmain(){pid_tpid;pid_tchildpid;if((pid=fork())==0){sleep(1);printf(“helloIamchild\n”);}else{childpid=wait(NULL);printf(“helloIamparent,childhasfinished:PID=%d\n”,childpid);}exit(0);}5.2进程编程•例程:wait系统调用2#includesys/wait.hintmain(){pid_tpid;pid_tchild_pid;intstatus;intn;printf(“forkprogramstaring\n”);if((pid=fork())==0){printf(“Iamchild\n”);sleep(10);}if(pid!=0){child_pid=wait(&status);printf(“Childhasfinished:PID=%d\n”,child_pid);if(WIFEXITED(status))printf(“Childexitedwithcode%d\n”,WEXITSTATUS(status));elseprintf(“Childterminatedabnormaily\n”);}exit(0);}5.2进程编程•exec系统调用:功能为装载新的程序,并转换到调用进程的内存控件execl、execlp和execle的参数个数是可变的execv和execvp的第二个参数是一个字符串数组#includeunistd.hintexecl(constchar*path,constchar*arg0,..,(char*)0);intexeclp(constchar*file,constchar*arg0,..,(char*)0);intexecle(constchar*path,constchar*arg0,..,(char*)0,char*constenvp[]);intexecv(constchar*path,char*constargv[]);intexecvp(constchar*file,char*constargv[]);intexecv(constchar*path,char*constargv[],char*constenvp[]);5.2进程编程•所有的exec系统调用都是用execve调用实现的execveexecveexecveexeclexecvpexecvexecleexeclp5.2进程编程实验:execlp系统调用#includeunistd.h#includestdio.hintmain(){printf(“Runningpswithexeclp\n”);execlp(“ps”,“ps”,“-ax”,0);printf(“Done.\n”);exit(0);}5.2进程编程实验:execl系统调用#includeunistd.h#includestdio.hintmain(intargc,char*argv[]){char*filename;if(argc!=2){fprintf(stderr,“usage:useupperfile\n”);exit(1);}filename=argv[1];if(!freopen(filename,“r”,stdin)){fprintf(stderr,“couldnotredirectstdinfromfile%s\n”,filename);exit(2);}execl(“./upper”,“upper”,0);perror(“couldnotexec./upper”);exit(3);}//upper.c#includeunistd.h#includestdio.hintmain(){intch;while((ch=getchar())!=EOF){putchar(toupper(ch));}exit(0);}5.2进程编程实验:exec和fork#includeunistd.hmain(){pid_tpid;switch(pid=fork()){case-1:fatal(“forkfailed”);break;case0:execl(“/bin/ls”,“ls”,“-l”,(char*)0);fatal(“execfailed”);break;default:wait((int*)0);printf(“iscompleted\n”);exit(0);}}intfatal(char*s){perror(s);exit(1);}5.2进程编程实验:fork与文件#includeunistd.h#includefcntl.hmain(){intfd;pid_tpid;charbuf[10];if((fd=open(“filedata”,O_RDONLY))==-1)fatal(“openfailed”);read(fd,buf,10);printpos(“Beforefork”,fd);switch(pid=fork()){case-1:fatal(“forkfailed”);break;case0:printpos(“Childbeforeread”,fd);read(fd,buf,10);printpos(“Childafterread”,fd);break;default:wait((int*)0);printpos(“Parentafterwait”,fd);}}intprintpos(constchar*string,intfiledes){off_tpos;if((pos=lseek(filedes,0,SEEK_CUR))==-1)fatal(“lseekfailed”);printf(“%s:%ld\n”,string,pos);}5.2进程编程进程终止:•main函数调用return•调用exit•调用_exit•调用abort•被一个信号终止5.2进程编程•exit函数与_exit函数exit函数作为c标准库的一部分。使程序正常终止并且返回父进程状态。#includestdlib.hintexit(intstatus);#includeunistd.hint_exit(status);5.2进程编程•abort函数异常终止一个程序#includestdlib.hvoidabort(void);#includestdlib.h#includestdio.hintmain(void){abort();ex
本文标题:Linux系统编程(第五章) 进程
链接地址:https://www.777doc.com/doc-5530166 .html