linux试验报告.docx
- 文档编号:6609229
- 上传时间:2023-01-08
- 格式:DOCX
- 页数:14
- 大小:20.37KB
linux试验报告.docx
《linux试验报告.docx》由会员分享,可在线阅读,更多相关《linux试验报告.docx(14页珍藏版)》请在冰豆网上搜索。
linux试验报告
西安郵電學院
Linux实验报告
题目1:
进程
题目2:
线程
题目3:
互斥
系部名称
:
计算机学院
专业名称
:
软件工程
班级
:
0802
学号
:
04085047
学生姓名
:
王晶晶
指导教师
:
陈莉君
时间
:
2010年10月29号------11月9号
实验1进程
1.1实验目的
通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间等方面的特点,
掌握在POSIX规范中fork和kill系统调用的功能和使用。
1.2实验要求
1.2.1实验环境要求
1.硬件
(1)主机:
PentiumIII以上;
(2)内存:
128MB以上;
(3)显示器:
VGA或更高;
(4)硬盘空间:
至少100MB以上剩余空间。
2.软件
Linux操作系统,内核2.4.26以上,预装有X-Window、vi、gcc、gdb和任
意web浏览器。
1.2.2学生实验前的准备工作
学习man命令的用法,通过它查看fork和kill系统调用的在线帮助,并阅读参
考资料,学会fork与kill的用法。
复习C语言的相关内容。
1.3实验内容
1.先猜想一下这个程序的运行结果。
假如运行“./process20”,输出会是什么样?
执行./process20会输出10个进程交替执行。
输入要删除的进程编号,回车则删除该进程,输入q,回车删除进程组,程序结束。
2.然后按照注释里的要求把代码补充完整,运行程序。
可以多运行一会儿,并在
此期间启动、关闭一些其它进程,看process的输出结果有什么特点,记录下这个结果。
3.开另一个终端窗口,运行“psaux|grepprocess”命令,看看process究竟启动了多少个进程。
回到程序执行窗口,按“数字键+回车”尝试杀掉一两个进程,再到另一个窗口看进程状况。
执行./forkTest10输入命令psaux|grep./forkTest后显示有12个进程在运行(10个子进程,1个父进程,最后一个为psaux|grep./forkTest命令的进程号),删除1号进程后,再输入psaux|grep./forkTest命令,则显示的进程数为11.
按q退出程序再看进程情况。
1.4回答下列问题。
1.你最初认为运行结果会怎么样?
进程交替执行,当输入某进程编号加回车后该进程会被杀死,不再输出,当输入q加回车后剩余的所有子进程都被杀死,程序运行结束。
2.实际的结果什么样?
有什么特点?
试对产生该现象的原因进行分析。
结果与上述的预期相同。
特点:
各进程交替执行。
无确定顺序。
分析:
当程序执行到for(i=0;i 这个过程不一定可以连续的执行下去,因为在该过程中,父进程随时可能抢到cpu,再次执行fork();创建另一个子进程或者执行else语句(由其上次执行到的位置决定)。 该子进程的执行与第一个子进程类似。 自此该3个进程交替执行,当父进程执行fork()时,则继续创建新的子进程以此类推。 直到父进程完成for(i=0;i 此时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.补充后的程序源代码。 #include #include #include #include #include #defineMAX_CHILD_NUMBER10 #defineSLEEP_INTERVAL2 intproc_number=0; voiddo_something(); intmain(intargc,char*argv[]) { intchild_proc_number=MAX_CHILD_NUMBER; inti; charch; pid_tchild_pid; pid_tpid[10]={0}; if(argc>1) { child_proc_number=atoi(argv[1]); child_proc_number=(child_proc_number>10)? 10: child_proc_number; } for(i=0;i { child_pid=fork(); if(child_pid==0) { proc_number=i; pid[i]=getpid(); do_something(); } elseif(child_pid<0) { perror("forkerror! \n"); } else { pid[i]=child_pid; } } while((ch=getchar())! ='q') { if(isdigit(ch)) { if(pid[ch-'0']! =-1) { kill(pid[ch-'0'],SIGTERM); pid[ch-'0']=-1; } } } kill(0,SIGTERM); return0; } voiddo_something() { for(;;) { printf("ThisprcessisNO.%*d\n",proc_number+3,proc_number); sleep(SLEEP_INTERVAL); } } 实验2线程 2.1实验目的 通过观察、分析实验现象,深入理解线程及线程在调度执行和内存空间等方面的特点,并掌握线程与进程的区别。 掌握在POSIX规范中pthread_create()函数的功能和使用方法 2.2实验要求 2.2.1实验环境要求 1.硬件 (1)主机: PentiumIII以上; (2)内存: 128MB以上; (3)显示器: VGA或更高; (4)硬盘空间: 至少100MB以上剩余空间。 2.软件 Linux操作系统,内核2.4.26以上,预装有X-Window、vi、gcc、gdb和任 意web浏览器。 2.2.2学生实验前的准备工作 阅读参考资料,了解线程的创建等相关系统调用。 2.3实验内容 按照注释里的要求把代码补充完整,正确编译程序后,先预计一下这个程序的运行结果。 具体的结果会是什么样? 运行程序。 开另一个终端窗口,运行“psaux”命令,看看thread的运行情况,注意查看thread的CPU占用率,并记录下这个结果。 预计输出的前三列数不相等,main_counter的值与sum的值相等,且为前三列显示的线程运行次数之和。 运行psaux命令后,./thread的CPU占用率为197 2.4实验中的问题 1.你最初认为前三列数会相等吗? 最后一列斜杠两边的数字是相等,还是大于或者 小于关系? 不会相等,因为三个进程交替执行,每个进程运行的时间及次数都不确定。 main_count的值应该等于sum的值等于3个线程执行次数的总和。 2.最后的结果如你所料吗? 有什么特点? 试对原因进行分析。 不,前3列的输出结果与预期结果相同,但main_count的值大于sum的值。 分析: 因为main_counter属于临界资源,可能会出现当一个线程正在执行main_counter++时,另一个线程也要执行main_counter++的情况,这样就会使main_counter的值不准确。 又线程运行顺序的不确定性(交替性),可能在一个线程执行了main_counter++后,还未执行counter[thread_num]++时,CPU便被主线程抢去,执行for(i=0;i 再输出个各线程巡行的次数,及main_counter和sum的值,结果与预期的理论值不符。 3.thread的CPU占用率是多少? 为什么会这样? 197。 因为三个线程调用的函数执行的是一个死循环for(;;),使得CPU的利用率过高。 4.thread_worker()内是死循环,它是怎么退出的? 你认为这样退出好吗? 输入q回车,主线程会退出while循环,执行return()函数,结束整个程序。 自然子线程也都被迫终止,死循环也就退出了! 这样的退出不好。 5: #include #include #include #include #include #defineMAX_THREAD3 unsignedlonglongmain_counter,counter[MAX_THREAD];//unsignedlonglong鏄瘮long杩橀暱鐨勬暣褰€? void*thread_worker(void*); intmain(intargc,char*argv[]) { inti,ch; intnum[3]; pthread_tthid,pthread_id[MAX_THREAD]={0}; for(i=0;i { num[i]=i; if(pthread_create(&thid,NULL,(void*)thread_worker,&num[i])==0) { pthread_id[i]=thid; //thread_worker(&i); } else { printf("threadcreaterfailed! \n"); //exit (1); } } do { unsignedlonglongsum=0; /*姹傛墍鏈夌嚎绋媍ounter鐨勫拰*/ for(i=0;i { sum+=counter[i]; printf("%d%llu",i,counter[i]); } printf("\n\n%llu\n%llu\n\n",main_counter,sum); }while((ch=getchar())! ='q'); return0; } void*thread_worker(void*p) { intthread_num; thread_num=*((int*)p); for(;;) { main_counter++; counter[thread_num]++; sleep (1); } returnNULL; } 实验3互斥 3.1实验目的 通过观察、分析实验现象,深入理解理解互斥锁的原理及特点 掌握在POSIX规范中的互斥函数的功能及使用方法 3.2实验要求 3.2.1实验环境要求 1.硬件 (1)主机: PentiumIII以上; (2)内存: 128MB以上; (3)显示器: VGA或更高; (4)硬盘空间: 至少100MB以上剩余空间。 2.软件 Linux操作系统,内核2.4.26以上,预装有X-Window、vi、gcc、gdb和任意web浏览器。 3.2.2学生实验前的准备工作 准备好上节实验完成的程序thread.c。 阅读参考资料,了解互斥锁的加解锁机制及相关的系统调用。 4.3实验内容 1.找到thread.c的代码临界区,用临界区解决main_counter与sum不同步的问题。 在使用到main_counter与sum临界资源的临界区上加上p,v操作。 修改后的thread.c的代码如下: #include #include #include #include #include #defineMAX_THREAD3 unsignedlonglongmain_counter,counter[MAX_THREAD];//unsignedlonglong鏄瘮long杩橀暱鐨勬暣褰€? pthread_mutex_tmutext=PTHREAD_MUTEX_INITIALIZER; pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER; void*thread_worker(void*); intmain(intargc,char*argv[]) { inti,ch; intnum[3]; pthread_tthid,pthread_id[MAX_THREAD]={0}; for(i=0;i { num[i]=i; if(pthread_create(&thid,NULL,(void*)thread_worker,&num[i])==0) { pthread_id[i]=thid; } else { printf("threadcreaterfailed! \n"); //exit (1); } } pthread_mutex_lock(&mutex); do { unsignedlonglongsum=0; /*姹傛墍鏈夌嚎绋媍ounter鐨勫拰*/ for(i=0;i { sum+=counter[i]; printf("%d%llu",i,counter[i]); } printf("\n\n%llu\n%llu\n\n",main_counter,sum); }while((ch=getchar())! ='q'); pthread_mutex_unlock(&mutex); pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutext); return0; } void*thread_worker(void*p) { intthread_num; thread_num=*((int*)p); for(;;) { pthread_mutex_lock(&mutext); main_counter++; counter[thread_num]++; sleep (1); pthread_mutex_unlock(&mutext); } returnNULL; } 仔细阅读程序,编译程序后,先预计一下这个程序的运行结果。 运行程序。 若程序没有响应,按ctrl+c中断程序运行,然后再重新运行,如此 反复若干次,记录下每次的运行结果。 若产生了死锁,请修改程序,使其不会死锁。 4.4实验中的问题 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.修改前补充的程序源代码 #include #include #include #include #include #defineLOOP_TIMES10000 pthread_mutex_tmutex1=PTHREAD_MUTEX_INITIALIZER; pthread_mutex_tmutex2=PTHREAD_MUTEX_INITIALIZER; void*thread_worker(void*); voidcritical_section(intthread_num,inti); intmain(void) { intrtn,i; pthread_tpthread_id=0; rtn=pthread_create(&pthread_id,NULL,thread_worker,NULL); if(rtn! =0) { printf("pthread_createERROR! \n"); return-1; } for(i=0;i { pthread_mutex_lock(&mutex1); pthread_mutex_lock(&mutex2); critical_section(1,i); pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex1); } pthread_mutex_destroy(&mutex1); pthread_mutex_destroy(&mutex2); return0; } void*thread_worker(void*p) { inti; for(i=0;i { pthread_mutex_lock(&mutex2); pthread_mutex_lock(&mutex1); critical_section(2,i); pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex1); } } voidcritical_section(intthread_num,inti) { printf("Thread%d: %d\n",thread_num,i); } 4.修改后补充的程序源代码 #include #include #include #include #include #defineLOOP_TIMES10000 pthread_mutex_tmutex1=PTHREAD_MUTEX_INITIALIZER; pthread_mutex_tmutex2=PTHREAD_MUTEX_INITIALIZER; void*thread_worker(void*); voidcritical_section(intthread_num,inti); intmain(void) { intrtn,i; pthread_tpthread_id=0; rtn=pthread_create(&pthread_id,NULL,thread_worker,NULL); if(rtn! =0) { printf("pthread_createERROR! \n"); return-1; } for(i=0;i { pthread_mutex_lock(&mutex1); pthread_mutex_lock(&mutex2); critical_section(1,i); //sleep (1); pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex1); } pthread_mutex_destroy(&mutex1); pthread_mutex_destroy(&mutex2); retu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 试验报告