实验九_POSIX线程机制一_第1页
实验九_POSIX线程机制一_第2页
实验九_POSIX线程机制一_第3页
实验九_POSIX线程机制一_第4页
实验九_POSIX线程机制一_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验九POSIX线程机制一实验目的:1. 理解进程与线程的区别;2. 实现单线程与多线程控制;3. 了解POSIX线程机制,使用常用的线程操作函数实验内容:1. 观察单线程程序和多线程程序的区别;2. 使用常用的线程操作函数。实验步骤:(一)“ hello world单线程程序调试并运行下面的程序,如图/hello world单线程程序# in elude con st NUM = 5;int mai n()/ void p_msg(char *);p_msg(hello);P_msg(worldn);1所示,观察输出结果,并分析原因void p_msg(char *m)int i;for(i

2、 = 0 ; i NUM ; i +)prin tf(%s,m); fflush(stdout);sleep(1);图1单线程程序(roatlora Lt:lod Ihoit raotltt liaJiacotida-k .cfg i .util inwL 廿 ll-lo* in u 11. log . sys Jogt .croutl 口 cnllujsL rco t g cc -q11 tzll.cles t I . : I 5 3 us rn in耳: type imi 弓 rm tr h wi l h prev ions inrp I i c i t dec ra t ionles 1

3、1.c18: warning; prev iou i np I i c j t dtcla ra t ion of p_TFg11 .: 12: usrn ing : p_iYne佃空 provioLsly iiipI it it ly do? larod to return iniH les LI . c :20 :2: 碣rniitg: noin亡 j L f nd of fileI rootflora Rj(is i too tti . / 1e s 11he 11qhe I lobe I lobe I lohe I lovor Id.wjt Idiw Idvut)r Idwu r I

4、d rootfloca llios t roo tW |结果分析:先运行 p_msg(hello),后运行p_msg(worldn),故先输出5个hello , 1个world 跟在后面,4个world换行回车。(二) 使用pthread_create创建线程如果希望一个程序能同时并发执行很多函数,它可以通过创建多个线程实现,只要将上面的程序做两个小的改动,即可让程序并发执行两个函数。图2中的程序是一个简单“ hello world ”多线程程序void *p_msg(void *m)int i;for(i = 0 ; i 5 ; i +) prin tf(%s,m); fflush(stdo

5、ut); sleep(1);return NULL;#i nclude #i nclude main ()pthread_t t1 , t2;void *p_msg(void *);pthread_create(&t1,NULL,p_msg,(void * )hello ); pthread_create(&t2,NULL,p_msg,(void * )worldn”); pthread_join(t1, NULL);pthread_join(t2, NULL);图2多线程程序提示:POSIX标准族中包含有线程标准,有关的系统调用名字以“ pthread_” 打头。为了使用这些函数,须对REE

6、NTRANT宏进行定义,该宏包括在头文件pthread.h中,链接这些线程函数库时要使用编译器命令的“-lpthread ”选项思考:结果:icoiloca ha I root# gcc -oltisi2.c - Ip ihreadif s i2 . c: n func I i on iih in:les |2 , c:S; rn ing ;; ing j rgnf pthread .rea t p from i nr打叩且 t ih W poini e rtypeit s t2 .c:9: vfiiniftg : paing jrg 3 of pihread_-crci11 from inn

7、pit ih I poinif r typ*te s 1224 7 2 : varnm 耳;no new ine a t e nd of f i leroo t-Moca 1 ho刃 t ana cunda-k .cfg J uu tro-o lr 14 h电 I IciMur l-d li I Iumof I1将 pthread_join 删除后:rQt(?iuua I hua l run t fl / Le s t2_2 he J lotMjr IdrodMoca I hcs i too t # ./test2_2he I lnwir Iri会这样是因为两个线程在sleep (1)的时间里

8、进程运行完毕结束。线程被迫结 束。iv. 进程放后台运行,用ps观察进程状态,用pstree观察是否有子进程产生。roolloca I hcs t ruo L ./ te i t5 A1 I2U1roor?loca Iho$ I rootle he I lor IdFID TTYnrrCJD2577 pis/fl0000:1)0wtl12181 pis/fl;()()test212184 pti/O00:00:01)PSf rootlocAIhoii roo t# hellouorId he I IqudtIdhe 11 nun r Idhe 1 lower Id-iioin?-irrmi n

9、i l一+-da sti-+-ps treeI-lestS-gnonv-piy-heI pc没有子进程产生v. 改写代码,使同样的输出内容由并发的父子进程实现。进程放后台运行,用ps观察进程状态。与先前的观察有什么不同?请分析原因, 体会进程和线程概念的差异。test3.c#i nclude const NUM = 5;int main() / void p_msg(char *);int p1;while(p 仁fork()=-1);if(p10) /* 主进程的处理*/int i;sleep(5);for(i = 0 ; i NUM ; i +) prin tf(hellon); slee

10、p(1);wait(0);exit(0);elseint i;sleep(5);for(i = 0 ; i NUM ; i +) prin tf(worldn); sleep(1);exit(0); 有子进程产生:-|jncne-termi nll在我所安装的la l_ba sh-+ps t ree-te s t31e 512linux版本中,ps只能显示父进程:j od l / loc-a Ih口生t i qo 订# pstie Ir IdFID TTYTJhf ED3110 pls/fl00:00:00 hash329900=00:00 teit3aaoa pls/oUO:00:(UJ p

11、s当子进程运行完,父进程未退出时可以看到子进程变为僵尸进程1*001:!* lor 3 1 h()t raal* psLID rrvTJMl CAD31W pLs/O0600:00 bash3271 pis/flQOiOOiOti tes.t33272 pis/fl00:00:00 tes-tS 3280 pis/flCO:00:0(! pa(三) 观察并发的线程运行图3中的程序,观察线程并发执行的效果及存在互相干扰的效果#i nclude #i nclude #i nclude void *Pri ntThread(void * );#defi ne Num_Threads 3int mai

12、 n()int i,ret;pthread_t a_thread;int ThdNumNum_Threads;for (i = 0; i Num_Threads; i+)ThdNumi = i;for(i = 0; i Num_Threads;i+)ret = pthread_create(&a_thread,NULL,Pri ntThread,(void *)& ThdNumi);if (ret = 0)prin tf(Thread laun ched succeddfullyn);i = getchar();return (0);void *Pri ntThread(void * num)

13、int i;for(i = 0;i 5; i+)prin tf(thread number is %dn,*(i nt *)n um);sleep(1);return NULL;图3多线程的并发思考:编译连接通过后,多次运行程序,查看输出结果,并分析结果产生的原因root1 oca Ihost roo1./pthreadsthread nurrber 0I bread nurrbe r i s 0Thread launched sucrcdilfu I ylliread nuliber 1 s 】th read nunbe r 】& 1Thread l-atknch&d succcdJfu 1

14、 lythread nunber i a 2thread n-uiibcr i2Thread lonched sycEdifu 1 lyilircad nunber is 0Llireaii nuiihe r i 1thread nunber i s 1ihi cad minbe r j s 0ilireid nuiiber 注 1Llireiil nuiibe r i i 1tliread iiunber i& 0ihiead minbe r i s 1Lliread nuiibor is 1一开始输出两个线程一样是由于线程运行比主程序快,最后面9个应该是线程竞争造成的。(四)编写字数统计工

15、具使用Linux下的多线程编程,编写类似 wc(字数统计)的工具,使得程序能 同时对两个文件进行字数统计,然后得到两个文件的总单词数。进程有独立的数 据空间,在此进程运行的所有线程都拥有对这些数据的访问权。在某一时刻只允许唯一的线程对变量进行访问。如果进程中的任何线程修改了某一个数据,所有拥有此数据的线程必须采取一定策略来避免访问冲突。区分单词的规则:凡是一个非字母或者数字的字符跟在字母或者数字的后 面,那么这个字母或者数字就是单词的结尾。本次实验编写的是带瑕疵的字数统计工具,问题留到下一次实验中用POSIX 的互斥量解决。两个线程共享一个通用计数器,每个线程分别负责对一个文件进 行计算,所有

16、的线程在检查到单词的时候对同一个计数器增值,但是允许线程在没有任何避免访问冲突策略的情况下来修改临界资源一一通用计数器,因而可能会产生脏数据。参考代码详见图4中的程序。所有线程对同一个计数器进行操作,并且同时进行。使用下述代码temp=total_words;sleep(1);total_words=temp+1;是为了延时,使产生脏数据的效果明显。也就是程序先将计数器当前的值存入寄存器中,加 1操作后,再将其写回到内存中。 当所有线程在同一时刻都进行读取内存一加1-写回”的序列操作完成对寄存器的操作。#include #include #include int total_words = 0

17、;main(int ac , char * av)pthread_t t1, t2;void *count_words(void *);if(ac!=3) printf(usage: %s file1 file2n, av0); exit(1); pthread_create(&t1,NULL,count_words,(void * ) av1); pthread_create(&t2,NULL,count_words,(void * ) av2); pthread_join(t1, NULL); pthread_join(t2, NULL); printf(%5d: total wordsn

18、, total_words);void *count_words(void *f)char *filename = (char * )f;FILE *fp;int c, temp, prevc = 0;if(fp = fopen (filename, r ) != NULL) while(c = getc(fp)!= EOF) if(!isalnum(c)& isalnum(prevc) temp=total_words;sleep(1); /* 延时,使产生脏数据 */ total_words=temp+1; prevc =c; fclose(fp); elseprin tf(err fil

19、e name);return NULL;图4单词统计工具思考:i. 编译连接通过后,多次运行程序,查看输出结果。Lhofit root I# J佔 vrdrd24; lota 1 wordsrooilofj II roo11 fl ”Am? rd2 u)rd4: Lu J uurdsii. 统计数据正确吗?如果错误,请分析原因。统计结果并不正确。我在 word内写入1个单词,在word2内写入4个单词。总 共应该是五个单词。temp=total_words;sleep(1);total_words=temp+1;程序先将计数器当前的值存入寄存器中,加1操作后,再将其写回到内存中。当所有线程在同

20、一时刻都进行 读取内存一加1-写回”的序列操作完成对寄存器的 操作。word1和word2内的第一个单词相当于只在中数上加了一次。iii. 删除sleep(1);语句,对运行结果有何影响?这能从本质上避免产生 脏数据吗?删除后运行结果变正确了,但这不能从本质上避免产生脏数据。sleep(1)只是使 发生错误的概率增大。ruutlhusl ruu l./wcl urd Mrd左5: lot-3 I words(五) 编程题创建两个并发线程,一个线程输出奇数,另一个线程则输出偶数。mywrite1.c#i nclude #include #include void *PrintThread(voi

21、d * );#define Num_Threads 2int main()int i,ret0,ret1;pthread_t a_thread;int ThdNumNum_Threads;for (i = 0; i Num_Threads; i+)ThdNum0 = 0;ThdNum1 = 1;ret0 = pthread_create(&a_thread,NULL,PrintThread,(void *)&ThdNum0); ret1 = pthread_create(&a_thread,NULL,PrintThread,(void *)&ThdNum1); if (ret0 = 0)printf(Thread launched succeddfullyn);if (ret1 = 0)printf(Thread launched succeddfullyn);i = getchar();return (0);void *PrintThread(void * num)int i;for(i = 0;i o tgee -0ri mi i tIho

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论