实验1多线程和多进程的管理目录基础知识介绍进程编程基础知识线程编程基础知识实验目的实验内容实验要求基础知识介绍进程编程基础知识进程标识符:每个进程都有一个非负整型表示的唯一进程ID,除了进程ID,每个进程还有一些其他的标识符。可通过下列函数来返回。pid_tgetpid(void);//返回调用进程的进程IDpid_tgetppid(void);//返回调用进程的父进程IDuid_tgetuid(void);//返回调用进程的实际用户IDuid_tgeteuid(void);//返回调用进程的有效用户IDgid_tgetgid(void);//返回调用进程的实际组IDgid_tgetegid(void);//返回调用进程的有效组ID基础知识介绍进程编程基础知识进程创建的时机用户登录:为用户创建一个进程。作业调度:将作业装入内存,分配资源,创建进程。提供服务:服务于某种服务请求,创建一系列的后台服务进程。应用请求:由应用进程本身创建,让子进程和自己并发运行。基础知识介绍进程编程基础知识进程的创建过程:取空白PCB,生成惟一的进程标识号。为新进程分配必要的资源(包括程序段、数据段、栈段)。初始化PCB。将新进程的PCB插入就绪队列。基础知识介绍进程编程基础知识Linux中进程的创建Linux启动在内核态,在系统初始化结束时,初始进程启动一个核心进程(称为init),除了init进程外,Linux中的所有进程都是由其他进程创建的。使用系统调用fork()进行进程的创建。子进程是父进程的映像,子进程除了进程的状态、标识和与时间有关的控制项外,其余都与父进程相同。基础知识介绍进程编程基础知识fork系统调用当进程调用fork创建子进程后,根据fork的返回值来判断:当前执行的是父进程的程序段还是子进程的程序段。返回值:等于0,当前进程是子进程。大于0,当前进程是父进程,返回值是子进程的ID。等于-1,创建失败。格式:intpid_tfork(void);头文件:#includesys/types.h//提供pid_t的定义#includeunistd.h基础知识介绍进程编程基础知识当一个程序中调用fork函数后,内核会完成如下工作:内核系统分配新的内存块和内核数据结构。复制原来的进程到新的进程。向运行进程集添加新的进程。将进程号返回给两个进程。基础知识介绍进程编程基础知识1.父进程为什么要创建子进程?多用户操作系统、竞争资源、创建子进程争夺资源、父子进程一起从fork处继续执行。2.父进程创建子进程后,子进程能不能执行不同的程序?答案是可以的,这种情况下,子进程从fork返回后要立即调用exec系统调用来实现。3.怎样才能使父进程在子进程结束之后才执行?调用wait系统调用来实现父子进程同步执行。基础知识介绍进程编程基础知识exec系统调用用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程完全由新程序代换,而新程序则从其main函数开始执行。因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。有六种不同的exec函数,它们被统称为exec函数。基础知识介绍进程编程基础知识execl(constchar*filepath,constchar*arg1,char*arg2......)execv(constchar*filepath,char*argv[])execle(constchar*filepath,constchar*arg1,constchar*arg2,.....,char*consenvp[])execve(constchar*filepath,char*argv[],char*constenvp[])execlp(constchar*filename,constchar*arg1,constchar*arg2.....)execvp(constchar*filename,char*argv[])基础知识介绍进程编程基础知识进程终止1)进程正常结束在进程执行期间调用exit系统调用。2)进程的异常结束在进程运行期间,由于出现错误或故障而被迫结束。exit系统调用格式:voidexit(status)参数status是调用进程终止时传递给父进程的值。如果调用进程还有子进程,则将其所用子进程的父进程改为1号进程。基础知识介绍进程编程基础知识wait系统调用wait函数用于使父进程阻塞,直到一个子进程结束。父进程调用wait,该父进程可能会:a)阻塞b)带子进程的终止状态立即返回c)出错立即返回格式:pid_twait(int*status)参数status是一个指向int类型的指针,用来保存被收集进程退出时的一些状态。但如果我们对子进程是如何死掉的毫不在意,则pid=wait(NULL);头文件:#includesys/types.h#includesys/wait.h基础知识介绍线程编程基础知识1.线程标识就像每个进程都有一个进程ID一样,每个线程也有一个线程ID,但线程ID只在它所属的进程环境中有效。定义方法为:pthread_tid;2.线程创建1)pthread库Linux下的多线程遵循POSIX线程接口,称为pthread。pthread是一套用户级线程库,具有很好的移植性。但在linux上实现时,却使用了内核级线程来完成,这样提高的线程的并发性。Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库pthread。gccexample.c-lpthread-oexample基础知识介绍线程编程基础知识2)pthread系统调用pthread_create():创建一个线程。pthread_join():阻塞当前的线程,直到另外一个线程运行结束。pthread_exit():终止当前线程。pthread_cancel():中断另外一个线程的运行。pthread_attr_init():初始化线程的属性。pthread_attr_setdetachstate():设置脱离状态的属性(决定这个线程在终止时是否可以被结合)。pthread_attr_getdetachstate():获取脱离状态的属性。pthread_attr_destroy():删除线程的属性。pthread_kill():向线程发送一个信号。基础知识介绍线程编程基础知识pthread_create函数用来创建一个线程,它的原型为:intpthread_create(pthread_t*tidp,pthread_attr_t*attr,void*(*start_routine)(void*),void*arg);参数1:指向线程标识符的指针。参数2:用来设置线程属性,若为NULL,则用默认属性。参数3:新线程运行函数的起始地址。参数4:运行函数的参数。正确返回:0。线程标识存放在thread中错误返回:非0的错误代码。基础知识介绍线程编程基础知识pthread_join函数用来等待一个线程的结束,函数原型为:intpthread_join(pthread_tth,void**thread_return);参数1:为等待终止的子线程标识符。参数2:用户定义的指针,它可以用来存储被等待线程的返回值。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止。基础知识介绍线程编程基础知识pthread_exit函数用来终止线程,函数原型为:voidpthread_exit(void*_retval);唯一的参数是函数的返回代码.只要pthread_join中的第二个参数thread_return不是NULL,这个值将被传递给thread_return。实验目的加深对进程概念的理解,明确进程与线程的区别。掌握Linux进程创建和撤销的方法,进一步认识并发执行的实质。了解多线程的程序设计方法。实验内容-多进程和多线程进程创建关系如图所示1号进程创建2,3号两个进程2号进程创建两个线程Thread1,Thread2Thread1:求(1~n)之间的素数Thread2:生成Fibonacci序列3号进程创建4,5号两个进程4号进程执行系统命令,ls,ps,cp等5号进程执行一个用户编写的可执行文件每个进程输出自己的进程ID和父进程的进程ID,观察分析,并画出程序的进程树结构。12345学号为奇数同学完成实验内容-多进程和多线程进程创建关系如图所示1号进程创建2,3号两个进程2号进程执行系统命令,ls,ps,cp等3号进程创建4,5号两个进程4号进程创建两个线程Thread1,Thread2Thread1:求(1~n)之间的素数Thread2:生成Fibonacci序列5号进程执行一个用户编写的可执行文件每个进程输出自己的进程ID和父进程的进程ID,观察分析,并画出程序的进程树结构。12345学号为偶数同学完成实验要求1.按照要求编写程序,放在相应的目录中,编译成功后执行,并分析实验结果。2.比较进程退出的不同方式之间的区别。3.了解fork、exec、exit、wait等系统调用的用法和原理。4.掌握多线程创建最常用的三个函数pthread_create,pthread_join和pthread_exit的用法。5.根据实际完成内容写实验报告,在报告中记录实验过程中遇到的问题和针对问题的解决方案。6.提交形式:压缩包,包含源码和实验报告。实验报告和压缩包命名都为:班号+学号+姓名+实验1。例:01+20151234+王小二+实验1。不接收命名错误的实验报告。提交至sakai。(01郭平,02石亮,03石锐,04何静媛)