linux进程线程管理实验报告Word格式.docx

上传人:b****7 文档编号:22629698 上传时间:2023-02-04 格式:DOCX 页数:15 大小:19.65KB
下载 相关 举报
linux进程线程管理实验报告Word格式.docx_第1页
第1页 / 共15页
linux进程线程管理实验报告Word格式.docx_第2页
第2页 / 共15页
linux进程线程管理实验报告Word格式.docx_第3页
第3页 / 共15页
linux进程线程管理实验报告Word格式.docx_第4页
第4页 / 共15页
linux进程线程管理实验报告Word格式.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

linux进程线程管理实验报告Word格式.docx

《linux进程线程管理实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《linux进程线程管理实验报告Word格式.docx(15页珍藏版)》请在冰豆网上搜索。

linux进程线程管理实验报告Word格式.docx

(2)内存:

128MB以上;

(3)显示器:

VGA或更高;

(4)硬盘空间:

至少100MB以上剩余空间。

2.软件

Linux操作系统,内核2.4.26以上,预装有X-Window、vi、gcc、gdb和任

意web浏览器。

2.2实验前的准备工作

学习man命令的用法,通过它查看fork和kill系统调用的在线帮助,并阅读参

考资料,学会fork与kill的用法。

复习C语言的相关内容。

三、实验内容

3.1补充POSIX下进程控制的残缺版实验程序

3.2回答下列问题:

1.你最初认为运行结果会怎么样?

2.实际的结果什么样?

有什么特点?

试对产生该现象的原因进行分析。

3.proc_number这个全局变量在各个子进程里的值相同吗?

为什么?

4.kill命令在程序中使用了几次?

每次的作用是什么?

执行后的现象是什么?

5.使用kill命令可以在进程的外部杀死进程。

进程怎样能主动退出?

这两种退

出方式哪种更好一些?

四、实验结果

4.1补充完全的源程序

#include<

stdio.h>

sys/types.h>

unistd.h>

signal.h>

ctype.h>

#defineMAX_CHILD_NUMBER10/*允许建立的子进程个数最大值*/

#defineSLEEP_INTERVAL1/*子进程睡眠时间*/

intproc_number=0;

/*子进程的编号,从0开始*/

voiddo_something();

intmain(intargc,char*argv[])

{

intchild_proc_number=MAX_CHILD_NUMBER;

/*子进程个数*/

inti,ch;

pid_tchild_pid;

pid_tpid[10]={0};

/*存放每个子进程的id*/

if(argc>

1){

child_proc_number=atoi(argv[1]);

child_proc_number=(child_proc_number>

10)?

10:

child_proc_number;

/*命令行参数中的第一个参数表示建立几个子进程,最多10个*/

}

/*建立child_proc_number个子进程

*子进程要执行

*proc_number=i;

*do_something();

*父进程把子进程的id保存到pid[i]*/

for(i=0;

i<

i++){

child_pid=fork();

if(child_pid==-1){

perror("

createrror!

\n"

);

return1;

}

elseif(child_pid>

0)

pid[i]=child_pid;

else{

proc_number=i;

do_something();

}

/*让用户选择杀死哪个进程。

输入数字(自编号)表示杀死该进程

*输入q退出*/

while((ch=getchar())!

='

q'

){

if(isdigit(ch)){

kill(pid[ch-'

0'

],SIGTERM);

wait(&

pid[ch-'

]);

kill(0,SIGTERM);

/*杀死本组的所有进程*/

return0;

}

voiddo_something(){

for(;

;

printf("

ThisisprocessNO.%*d\n"

proc_number+3,proc_number);

sleep(SLEEP_INTERVAL);

4.2回答上述实验内容中的问题

1.预期结果:

会持续输出0-9号进程,直到输入数字键+回车,则会杀死该进程,接下来的输出将不会有该进程号,当输入q+回车,则退出程序。

2.实际结果:

与预期差不多,因输入进程总数20大于设定的最大进程数,因此按进程数10来处理。

随机输出0-9号进程,sleep(SLEEP_INTERVAL),循环输出,直到输入数字键,则会杀死该数字对应的进程,直到输入q退出循环,然后杀死本组所有进程。

分析:

每创建一个子进程时,将其pid存储在pid[i]中,i存储在proc_number,然后调用死循环函数do_something(),输出该进程的代号proc_number;

当输入数字键时,主进程会执行kill(pid[ch-'

],SIGTERM),从而杀死(ch-‘0’)号进程。

当输入q时循环退出,kill(0,SIGTERM),杀死本组所有进程。

程序退出。

3.proc_number这个全局变量在各个子进程里的值相同,因为子进程相互独立,资源互不影响。

4.kill命令在程序中使用了2次:

kill(pid[ch-'

第一次是杀死该进程号pid[ch-‘0’],执行后接下来的结果中不会有该进程号,用另一个终端打开,使用命令psaux|grepprocess,因为子进程先于父进程退出,则被杀死的进程为僵死状态,但我加了行代码wait(&

]),就会使该子进程真正结束。

第二次是杀死本组所有进程。

即主进程以及它创建的所有子进程。

执行后程序退出,进程结束。

5.进程在main函数中return,或调用exit()函数都可以正常退出。

而使用kill命令则是异常退出。

当然是正常退出比较好,若在子进程退出前使用kill命令杀死其父进程,则系统会让init进程接管子进程。

当用kill命令使得子进程先于父进程退出时,而父进程又没有调用wait函数等待子进程结束,子进程处于僵死状态,并且会一直保持下去,直到系统重启。

子进程处于僵死状态时,内核只保存该进程的必要信息以被父进程所需,此时子进程始终占着资源,同时减少了系统可以创建的最大进程数。

实验二:

线程管理

通过观察、分析实验现象,深入理解线程及线程在调度执行和内存空间等方面的特点,并掌握线程与进程的区别。

掌握在POSIX规范中pthread_create()函数的功能和使用方法。

阅读参考资料,了解线程的创建等相关系统调用。

1.你最初认为前三列数会相等吗?

最后一列斜杠两边的数字是相等,还是大于或者

小于关系?

2.最后的结果如你所料吗?

试对原因进行分析。

3.thread的CPU占用率是多少?

为什么会这样?

4.thread_worker()内是死循环,它是怎么退出的?

你认为这样退出好吗?

pthread.h>

#defineMAX_THREAD3/*线程的个数*/

unsignedlonglongmain_counter,counter[MAX_THREAD];

/*unsignedlonglong是比long还长的整数*/

void*thread_worker(void*);

intmain(intargc,charargv[]){

inti,rtn;

charch;

pthread_tpthread_id[MAX_THREAD]={0};

/*存放每个线程的id*/

MAX_THREAD;

pthread_create(&

pthread_id[i],NULL,thread_worker,(void*)i);

/*用pthread_create建一个普通的线程,线程id存入pthread_id[i],线程执行的函数是thread_worker,并i作为参数传递给线程*/

/*用户按一次回车执行下面的循环体一次。

按q退出*/

do{

unsignedlonglongsum=0;

for(i=0;

sum+=counter[i];

/*求所有线程的counter的和*/

printf("

counter[%d]=%llu\n"

i,counter[i]);

main_counter=%llu/sum=%llu\n"

main_counter,sum);

}while((ch=getchar())!

void*thread_worker(void*p){

intthread_num;

thread_num=(int)p;

/*把main中的i的值传递给thread_num*/

main_counter++;

counter[thread_num]++;

4.3回答上述实验内容中的问题

1.试验运行前我认为前三列数不会相等,因为三个线程运行次数是随机的,结果不可预料,当然counter[i]值不会一定相等。

而我认为main_counter与sum值应该是相等的。

因为都是三个线程的counter之和。

2.而实验结果是前三列数确实不相等。

不过main_counter与sum的值也不相等,main_counter<

sum,经分析讨论得出解释:

因为三个线程在共同争取运行thread_worker()函数,比如main_counter初值为0,pthread_id[0]执行之后main_counter+1,此时还未来得及将值赋给main_counter,这时的main_counter还是0;

pthread_id[1]也执行这个函数,main_counter+1,若此时在1号线程将main_counter+1的值还未赋给main_counter,即这时的main_counter还是0,pthread_id[2]也来执行这个函数,main_counter+1,此时三个线程才将加完之后的值赋给main_counter,则main_counter=0+1=1,而真正执行次数sum=0+1+1+1=3。

main_counter<

sum。

3.thread的CPU占用率在我的机子上执行结果是181,因为三个线程是无限循环的运行,使得cpu占用率很高。

4.thread_worker()函数内是死循环,退出时因为主函数中设置的输入q时循环退出。

输入q时主进程执行退出,return退出程序,则子线程也强制退出。

这样退出不好。

实验三:

互斥

通过观察、分析实验现象,深入理解理解互斥锁的原理及特点

掌握在POSIX规范中的互斥函数的功能及使用方法

准备好上节实验完成的程序thread.c。

阅读参考资料,了解互斥锁的加解锁机制及相关的系统调用。

3.1找到thread.c的代码临界区,用临界区解决main_counter与sum不同步的问题。

3.2阅读下列代码,回答问题:

#defineLOOP_TIMES1000

pthread_mutex_tmutex1=PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_tmutex2=PTHREAD_MUTEX_INITIALIZER;

void*thread_worker(void*);

voidcritical_section(intthreadd_num,inti);

intmain(intargc,char*argv[]){

intrtn,i;

pthread_tpthread_id=0;

rtn=pthread_create(&

pthread_id,NULL,thread_worker,NULL);

if(rtn!

=0){

pthread_createERROR!

return-1;

LOOP_TIMES;

pthread_mutex_lock(&

mutex1);

mutex2);

critical_section(1,i);

pthread_mutex_unlock(&

pthread_mutex_destroy(&

void*thread_worker(void*p){

inti;

critical_section(2,i);

voidcritical_section(intthread_num,inti){

printf("

Thread%d:

%d\n"

thread_num,i);

1.你预想deadlock.c的运行结果会如何?

2.deadlock.c的实际运行结果如何?

多次运行每次的现象都一样吗?

4.1通过加锁可修改thread.c程序,使得main_counter与sum值同步,源代码如下:

#defineMAX_THREAD3

pthread_mutex_tmain_counter_mutex=PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_tcounter_mutex=PTHREAD_MUTEX_INITIALIZER;

counter_mutex);

intthread_num;

thread_num=(int)p;

for(;

pthread_mutex_lock(&

main_counter_mutex);

main_counter++;

pthread_mutex_unlock(&

counter[thread_num]++;

4.2回答上述实验要求中的问题:

1.程序运行会出现中止现象,可能会资源互斥。

2.实际运行时程序会在运行期间中止,出现死锁现象。

多次运行之后现象都一样。

解释如下:

主线程申请mutex1资源,而子线程申请mutex2资源,此时主线程继续申请mutex2资源,子线程来申请mutex1资源,而mutex2资源还未被子线程释放,主线程无法申请到,同样的,mutex1资源未被主线程释放则子线程也无法申请到,此时便处于无限循环等待,形成死锁。

修改后的程序:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 纺织轻工业

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1