您好,欢迎访问三七文档
xxx操作系统课程实验报告书院系名称:xxx学生姓名:xxx专业名称:xxx班级:xxx学号:xxx时间:2012年10月22日至2012年11月1日实验题目进程管理实验一、实验目的1)熟悉Linux下进程管理和相关的系统调用2)通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间等方面的特点,掌握在POSIX规范中fork和kill系统调用的功能和使用。3)通过观察、分析实验现象,深入理解线程及线程在调度执行和内存空间等方面的特点,并掌握线程与进程的区别。掌握在POSIX规范中pthread_create()函数的功能和使用方法。4)通过观察、分析实验现象,深入理解互斥锁的原理及特点,掌握在POSIX规范中的互斥函数的功能及使用方法。二、实验环境Linuxshell1.硬件(1)主机:PentiumIII以上;(2)内存:128MB以上;(3)显示器:VGA或更高;(4)硬盘空间:至少100MB以上剩余空间。2.软件Linux操作系统,内核2.4.26以上,预装有X-Window、vi、gcc、gdb和任意web浏览器。三、实验内容A、Linux下用线程模拟实现“生产者—消费者”同步问题算法思想:varmutex,empty,full:semaphore:=1,n,0;buffer:array[0,…,n-1]ofitem;in,out:integer:=0,0;beginparbeginproducer:beginrepeat…produceranitemnextp;…wait(empty);wait(mutex);buffer(in):=nextp;in:=(in+1)modn;signal(mutex);signal(full);untilfalse;endconsumer:beginrepeat…wait(full);wait(mutex);nextc:=buffer(out);out:=(out+1)modn;signal(mutex);signal(empty);…consumeranitemnextc;untilfalse;endparendend流程图:函数调用的相互示意图:程序设计(源代码附后);运行结果:Main()函数初始化变量同步信号量互斥信号量创建N个生产者进程创建N个消费者进程生产者方法producer()消费者方法consumer()销毁所有进程开始Main()初始化变量(同步信号量,互斥信号量)创建N个生产者进程创建N个消费者进程生产者方法Producer()消费者方法Consumer()销毁所有进程结束ReturnB、补全代码:进程通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间等方面的特点,掌握在POSIX规范中fork和kill系统调用的功能和使用。学习man命令的用法,通过它查看fork和kill系统调用的在线帮助,并阅读参考资料,学会fork与kill的用法。复习C语言的相关内容。实验过程先猜想一下这个程序的运行结果。假如运行“./process20”,输出会是什么样?然后按照注释里的要求把代码补充完整,运行程序。可以多运行一会儿,并在此期间启动、关闭一些其它进程,看process的输出结果有什么特点,记录下这个结果。开另一个终端窗口,运行“psaux|grepprocess”命令,看看process究竟启动了多少个进程。回到程序执行窗口,按“数字键+回车”尝试杀掉一两个进程,再到另一个窗口看进程状况。按q退出程序再看进程情况。问题回答下列问题,写入实验报告。1.你最初认为运行结果会怎么样?进程交替执行,当输入某进程编号加回车后该进程会被杀死,不再输出,当输入q加回车后剩余的所有子进程都被杀死,程序运行结束。2.实际的结果什么样?有什么特点?试对产生该现象的原因进行分析。结果与上述的预期结果相同。特点:各进程交替执行。无确定顺序。分析:当程序执行到for(i=0;ichild_proc_number;i++)循环后,调用fork()函数创建第一个子进程,然后父进程与该子进程交替执行,当子进程抢到cpu时继续往下执行if(child_pid==0)语句中的程序段,若在执行到do_something();语句时,则调用该函数,执行死循环for(;;)输出该进程的相关内容,并在输出语句后加上sleep(SLEEP_INTERVAL);语句,给其他进程抢占cpu的机会。这个过程不一定可以连续的执行下去,因为在该过程中,父进程随时可能抢到cpu,再次执行fork();创建另一个子进程或者执行else语句(由其上次执行到的位置决定)。该子进程的执行与第一个子进程类似。自此该3个进程交替执行,当父进程执行fork()时,则继续创建新的子进程以此类推。直到父进程完成for(i=0;ichild_proc_number;i++)循环,child_proc_number个子进程创建完成。此时child_proc_number个子进程加一个父进程一起交替性运行,当父进程再次抢到cpu时,则执行while((ch=getchar())!='q')循环时,则按用户的输入杀死相应的进程。用户输入q时,则杀死子进程组,while((ch=getchar())!='q')循环结束,当执行return0;语句后该父进程也结束,整个程序结束。3.proc_number这个全局变量在各个子进程里的值相同吗?为什么?不相同。因为子进程会把父进程的所有资源复制一份。而父进程在创建一个新的子进程时的i值都不同,当新创建子进程执行时,将i赋值给该子进程的变量proc_number。4.kill命令在程序中使用了几次?每次的作用是什么?执行后的现象是什么?当输入要删除的进程编号时会调用一次kill,最后输入q结束时会调用一次kill。输入要删除的进程编号后,执行的结果为:输出除过已被删掉的进程的其余进程信息。输入q则显示“已终止”,整个程序执行结束。5.使用kill命令可以在进程的外部杀死进程。进程怎样能主动退出?这两种退出方式哪种更好一些?进程自己调用exit()或程序执行完后return().进程自己调用exit()结束的方式会比较好。6.把你的程序源代码附到实验报告后。C、补全代码:线程通过观察、分析实验现象,深入理解线程及线程在调度执行和内存空间等方面的特点,并掌握线程与进程的区别。掌握POSIX规范中pthread_create()函数的功能和使用方法。阅读参考资料,了解线程的创建等相关系统调用。实验过程按照注释里的要求把代码补充完整,正确编译程序后,先预计一下这个程序的运行结果。具体的结果会是什么样?运行程序。开另一个终端窗口,运行“psaux”命令,看看thread的运行情况,注意查看thread的CPU占用率,并记录下这个结果。问题回答下列问题,写入实验报告。1.你最初认为前三列数会相等吗?最后一列斜杠两边的数字是相等,还是大于或者小于关系?不会相等,因为三个线程交替执行,每个线程运行的时间及次数都不确定。Maincount的值应该等于sum的值等于三个线程执行次数的总和。2.最后的结果如你所料吗?有什么特点?对原因进行分析。不,前3列的输出结果与预期结果相同,但main_count的值大于sum的值。分析:因为maincounter属于临界资源,可能会出现当一个线程正在执行main_counter++时,另一个线程也要执行main_counter++的情况,这样就会使main_counter的值不准确。又线程运行顺序的不确定性(交替性),可能在一个线程执行了main_counter++后,还未执行counter[thread_num]++时,CPU便被主线程抢去,执行for(i=0;iMAX_THREAD;i++)循环,使sum+=counter[i];此时sum的值便比main_counter的值小了。再输出个各线程巡行的次数,及main_counter和sum的值,结果与预期的理论值不符。3.thread的CPU占用率是多少?为什么会这样?197。因为三个线程调用的函数执行的是一个死循环for(;;),使得CPU的利用率过高。4.thread_worker()内是死循环,它是怎么退出的?你认为这样退出好吗?输入q回车,主线程会退出while循环,执行return()函数,结束整个程序。自然子线程也都被迫终止,死循环也就退出了!这样的退出不好。5.把你的程序源代码附到实验报告后。并请保留源代码,下次实验需要使用。D、补全代码:互斥通过观察、分析实验现象,深入理解理解互斥锁的原理及特点掌握在POSIX规范中的互斥函数的功能及使用方法。准备好上节实验完成的程序thread.c。阅读参考资料,了解互斥锁的加解锁机制及相关的系统调用。找到thread.c的代码临界区,用临界区解决main_counter与sum不同步的问题。PTHREAD_MUTEX_NORMAL:不检测死锁,如果等待一个已经锁定的互斥量将会一直等待,即使是同一个线程锁定互斥量两次也会造成死锁,解除有其他线程锁定的互斥量将会引起不确定行为PTHREAD_MUTEX_ERRORCHECK:检测错误,一个线程重新锁定同一个锁会返回EDEADLK,如果解锁由其它线程锁定的互斥量或者没有锁定的互斥量就会返回错误PTHREAD_MUTEX_RECURSIVE:线程可以多次锁定同一个互斥锁,并且需要解锁和锁定次数对应,尝试解除没有锁定的互斥锁和解除由其他线程锁定的互斥锁将会引起错误。PTHREAD_MUTEXT_DEFAULT:重复锁定一个锁会导致不确定行为,其他和NORMAL相同。(一般来说它会映射到PTHREAD_MUTEX_NORMAL)实验过程仔细阅读程序,编译程序后,先预计一下这个程序的运行结果。运行程序。若程序没有响应,按ctrl+c中断程序运行,然后再重新运行,如此反复若干次,记录下每次的运行结果。若产生了死锁,请修改程序,使其不会死锁。问题回答下列问题,写入实验报告。1.你预想deadlock.c的运行结果会如何?线程1,2会交替运行,且执行到一半会终止。2.deadlock.c的实际运行结果如何?多次运行每次的现象都一样吗?为什么会这样?代码修改前代码修改后交替执行!每次执行到一半都会终止。每次运行的结果不同。终止是因为,线程的推进顺序不合法。如果在线程1执行pthread_mutex_lock(&mutex1);语句,申请1号资源成功后,线程2又执行pthread_mutex_lock(&mutex2);语句,申请2号资源成功。当线程1想要申请2号资源,即执行pthread_mutex_lock(&mutex2);语句或线程2想要申请1号资源,即执行pthread_mutex_lock(&mutex1);时,这两个线程将陷入无限的等待状态而产生死锁。为避免死锁的产生,则应调换线程1或线程2对1,2号资源加锁的顺序。即使线程1,2对1,2号资源的加锁顺序一致。即一次性为其分配了它所需要的所有资源,避免了死锁的产生。3.把修改后的两个程序的源代码附在实验报告后。四、调试情况,设计技巧及体会1、对自己设计进行评价,指出合理和不足之处,提出改进的方案。关于生产者—消费者:在实验前,对于互斥信号量和共享信号量还有一些不明白,经过实验,对此已经理解了,也明白了对互斥信号量加锁、解锁的重要性。在检查的时候,我只实现了一个生产者和一个消费者的情况,经过学长的帮助与讲解,在后期的代码完善中,我又加紧修改,完成了有N个生产者和N个消费者的情况,并且通过观察运行结果,更加深刻的理解了互斥和共享的概念。在多道程序环境下,当程序并发执行时,由于资源共享和进程合作,使处于同一个系统中的诸进程之间可能存在着两种形式的制约关系:间接相互制约关系(互斥关系)和直接相互制约关系(同步关系)。对于临界资源,诸进程间应采取互斥方式,实现对这种资源的共享。人们把在每个进程中访问临界资源的那段代码称为临界区。关于补全代码(进程、线程、互斥)
本文标题:进程管理实验
链接地址:https://www.777doc.com/doc-5526959 .html