进程 线程.docx
- 文档编号:2529311
- 上传时间:2023-05-03
- 格式:DOCX
- 页数:12
- 大小:18.97KB
进程 线程.docx
《进程 线程.docx》由会员分享,可在线阅读,更多相关《进程 线程.docx(12页珍藏版)》请在冰点文库上搜索。
进程线程
西安郵電大學
操作系统课程实验
报告书
院系名称
:
计算机学院
学生姓名
:
张萌萌
专业名称
:
软件工程
班级
:
软件1001
学号
:
123456
时间
:
2012年10月25日至2012年11月5日
实验题目:
进程(补代码)
一、实验目的与要求
1.目的
●通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间等方面的特点,掌握在POSIX规范中fork和kill系统调用的功能和使用。
●通过观察、分析实验现象,深入理解线程及线程在调度执行和内存空间等方面的特点,并掌握线程与进程的区别。
●通过观察、分析实验现象,深入理解理解互斥锁的原理及特点掌握在POSIX规范中的互斥函数的功能及使用方法。
2.要求
●学习man命令的用法,通过它查看fork和kill系统调用的在线帮助,并阅读参考资料,学会fork与kill的用法。
复习C语言的相关内容
●掌握POSIX规范中pthread_create()函数的功能和使用方法.了解线程的创建等相关系统调用。
二、实验环境
Ubuntu10.10shell+Vim+gcc编译器
三.实验内容
创建进程,并且让子进程去作死循环,通过父进程去管理杀死子进程,通过调用kill()函数实现。
4、回答相关问题
补缺以下三段代码,并回答问题。
将设计分析过程和源代码写入实验报告。
(1)进程
代码:
/*POSIX下进程控制的实验程序残缺版*/
#include
#include
#include
#include
#include
#include
#defineMAX_CHILD_NUMBER10/*允许建立的子进程个数最大值*/
#defineSLEEP_INTERVAL2/*子进程睡眠时间*/
#defineDEBUG0
intproc_number=0;/*子进程的自编号,从0开始*/
voiddo_something();
intmain(intargc,char*argv[])
{
/*子进程个数*/
intchild_proc_number=MAX_CHILD_NUMBER;
inti,ch;
intfd;
pid_tchild_pid;
pid_tpid[10]={0};/*存放每个子进程的id*/
#ifDEBUG
for(i=0;i<10;i++){
printf("pid[%d]:
%d\n",i,pid[i]);
}
#endif
if(argc>1)/*命令行参数第一个参数表示子进程个数*/
{
child_proc_number=atoi(argv[1]);
child_proc_number=(child_proc_number>10)?
MAX_CHILD_NUMBER:
child_proc_number;
}
for(i=0;i { /*填写代码,建立child_proc_number个子进程要执行 *proc_number=i; *do_something(); *父进程把子进程的id保存到pid[i] **/ proc_number=i; child_pid=fork(); switch(child_pid){ case0: pid[i]=getpid(); printf("pid[%d]: %d\n",i,pid[i]); do_something(); break; case-1: perror("fork"); exit(-1); default: proc_number=i; pid[proc_number]=child_pid; break; } } #ifDEBUG for(i=0;i<10;i++){ printf("pid[%d]: %d\n",i,pid[i]); } #endif /*让用户选择杀死进程,数字表示杀死该进程,q退出*/ while((ch=getchar())! ='q') { if(isdigit(ch)) { /*填写代码,向pid[ch-'0']发信号SIGTERM, *杀死该子进程*/ printf("\n#pid[%d]: %dDead! \n",ch-'0',pid[ch-'0']); kill(pid[ch-'0'],SIGTERM); } } printf("Youwillkillallprocesswhichbelongstocurrentprocess! \n"); for(i=3;i>0;i--){ printf("%d...\n",i); sleep (1); } printf(">. ! ! ! \n"); /*在这里填写代码,杀死本组的所有进程*/ if(-1==kill(0,SIGTERM)){ perror("kill"); exit(-2); } return0; } voiddo_something() { for(;;) { //此处需要加上\n来刷新缓冲,否则的话不会打印此句 printf("ThisisprocessNo.%danditspidis%d\n",proc_number,getpid()); sleep(SLEEP_INTERVAL);/*主动阻塞两秒钟*/ } } 1.你最初认为运行结果会怎么样? 答: 随机创建一个进程,子进程调用do_something()函数! 会无限的循环下去! 2.实际的结果什么样? 有什么特点? 试对产生该现象的原因进行分析。 答: 通过main()函数代参数,随机的创建若干进程! 例如: ./process3创建3个进程随机的给出这3个进程的pid号,并且每次等待sleep (2);输出一次 3个进程的运行状态。 父进程创建子进程,通过fork()函数创建! 父进程中会返回子进程的pid 把这个保存在pid[i]数组中; 3.proc_number这个全局变量在各个子进程里的值相同吗? 为什么? 答: 不相同,因为每个进程是独立的,内存会为每个进程分配独立的运行空间例如: PCB进程块。 4.kill命令在程序中使用了几次? 每次的作用是什么? 执行后的现象是什么? 答: 执行了0-n(n<10)次,作用是杀死对应的进程。 每次执行的结果就是杀死一个进程,循环打印时,不再打印该进程的信息,归还内存分配给它的资源。 5.使用kill命令可以在进程的外部杀死进程。 进程怎样能主动退出? 这两种退出方式哪种更好一些? 答: 进程运行完退出属于正常的退出,而调用kill()是在进程运行过程中删除,这样做会破坏内存信息,我认为主动退出好些。 (1)线程 /* *ProgramName: 2.c *Author: Jiajie.Chen *Date: 2012/10/29 *Description: OperatingSystemhomework *POSIX下线程控制的实验程序残缺版 **/ #include #include #include #include #include //#defineDEBUG0 #defineMAX_THREAD3/*线程的个数*/ unsignedlonglongmain_counter,counter[MAX_THREAD]; void*thread_worker(void*); intmain(intargcm,char*argv[]) { inti,rtn,ch; inta[MAX_THREAD]; pthread_tthid; pthread_tpthread_id[MAX_THREAD]={0};//存放线程ID #ifdefDEBUG for(i=0;i printf("counter[%d]=%llu\n",i,counter[i]); } getchar(); #endif for(i=0;i /*用pthread_create建立一个普通线程*/ /*线程ID存入pthread_id[i],线程执行*/ /*函数是thread_worker,并将i作为参数*/ /*传递给线程*/ //a[i]=i; if(-1==(pthread_id[i]=pthread_create(&thid,NULL,thread_worker,&i))){ perror("pthread_create"); printf("pthread_id[%d]wrong! \n",i); } printf("pthread_id[%d]=%d\n",i,thid); } do{ /*用户按一次回车执行下面的循环体一次,按Q退出*/ unsignedlonglongsum=0; /*求所有线程的counter的和*/ for(i=0;i /*求所有的counter的和*/ sum+=counter[i]; printf("counter[%d]=%llu\n",i,counter[i]); } printf("main_counter/sum=%llu/%llu\n",main_counter,sum); }while(((ch=getchar())! ='q')&&(ch! ='Q')); return0; } void*thread_worker(void*p){ intthread_num; /*将main中的i的值传递给thread_num*/ thread_num=*((int*)p); for(;;){ #ifdefDEBUG sleep (1); printf("thread_num=%d\n",thread_num); #endif counter[thread_num]++;//本线程的counter加1 main_counter++;//主counter加1 } } 问题 1.你最初认为前三列数会相等吗? 最后一列斜杠两边的数字是相等,还是大于或者小于关系? 答: 不会相等! 最后一列小于. 2.最后的结果如你所料吗? 有什么特点? 对原因进行分析。 答: 没有按我想的输出结果.上面3个都是随机调用子线程所以不可能相等./号两边的数由于计算机计算的比较快,当你输出这句的时候你要输出的值其实有发生了变化.所以要加上互斥锁保证输出的时候不会反生变化. 3.thread的CPU占用率是多少? 为什么会这样? 答: 通过命令psaux查看 cpu的利用率191.创建的线程都是在一个进程里面的,所以每个进程的自加运算都是在一个进程中实现的所以cpu中只出现两./thread一个进程. 4.thread_worker()内是死循环,它是怎么退出的? 你认为这样退出好吗? 答: thread_worker()内是死循环/它的退出是因为主线程结束了,所以子线程就会结束. 我认为这样退出不好.和那个kill()命令一样都是在程序运行中突然结束的。 (1)互斥锁 代码: #include #include #include #include #include #defineLOOP_TIMES10000 pthread_mutex_tmutex1=PTHREAD_MUTEX_INITIALIZER;/*用宏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;/*存放子线程的id*/ 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(&mutex1); pthread_mutex_lock(&mutex2); 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); } 问题: 3.你预想deadlock.c的运行结果会如何? 答: 输出所有的数字。 4.deadlock.c的实际运行结果如何? 多次运行每次的现象都一样吗? 为什么会这样? 答: 由于产生两死锁,程序没有执行完。 多次运行一次比一次输出的少。 我认为是cpu还没有来的急释放,每次申请锁的资源,导致第2次运行的时候没申请几个资源有死锁了。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 线程