还剩9页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
实验七:Linux多线程编程4课时实验目的掌握线程的概念;熟悉Linux下线程程序编译的过程;掌握多线程程序编写方法实验原理:为什么有了进程的概念后还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应当选用多线程?我们一方面必须回答这些问题1多线程概念使用多线程的理由之一是和进程相比,它是一种非常”节俭”的多任务操作方式运营于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间使用多线程的理由之二是线程间方便的通信机制同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用这不仅快捷,并且方便2多线程编程函数Linux系统下的多线程遵循POSIX线程接口,称为pth「ead编写Linux下的多线程程序,需要使用头文献pthread.h连接时需要使用库Iibpthread.apthread」在头文献/usr/include/bits/pthreadtypes.h中定义typedefunsignedlongintpthread_t;它是一个线程的标记符函数pthread_create用来创建一个线程,它的原型为externintpthread_createpthread_t*threadconstpthreadattrt*a11rvoid**start_routinevoid*void*arg;第一个参数为指向线程标记符的指针,第二个参数用来设立线程属性,第三个参数是线程运营函数的起始地址最后一个参数是运营函数的参数函数pth「ead_jin用来等待一个线程的结束函数原型为externintpthread_joinpthread_tthvoid**thread_rentmainvoidpthread_tthread pthread_attr_tattr;intno=0res void*lhrd_ret;srandtimeNULL;/*初始化线程属性对象*/res=pthread_attrjnitattr;ifres!=0printfCreateattributefailed\n;exitres;/*设立线程绑定属性*/res=pthread_attr_setscopeattr;PTHREAD_SC0PE_SYSTEM;/*设立线程分离属性*/res+=pthread_attr_setdetachstateattrPTHREAD_CREATE_DETACHED;ifres!=0printfSettingattributefailed\n;exitres;res=pthread_createthreadattr.thrd_funcNULL;ifres!=0printfCreatethreadfaiIed\n;exitres;}/*释放线程属性对象*/pthread_attr_destroyattr;printfCreatetreadsuccess\n whi1e!finish_fIagPrintfWaitingforthreadtofinish...\n sleep2;return0;
4、完毕教材上多线程实验的实验内容并分析程序的执行结果实验总结由运营结果可以看出,创建线程、释放资源按照顺序,而每个线程的运营和结束是独立与并行的turn);第一个参数为被等待的线程标记符,第二个参数为一个用户定义的指针它可以用来存储被等待线程的返回值函数pthread_exit的函数原型为externvoidpthread_exit(void*retval);唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return不是NULL这个值将被传递给thread_returno3修改线程的属性线程属性结构为pthread_attr_t它在头文献/usr/inc1ude/pthread.h中定义属性值不能直接设立,须使用相关函数进行操作,初始化的函数为pthread_attr_init这个函数必须在pthread_create函数之前调用设立线程绑定状态的函数为pthread_attr_setscope它有两个参数,第一个是指向属性结构的指针,第二个是绑定类型,它有两个取值:PTHREAD_SCOPESYSTEM(绑定的)和PTHREAD_SCOPE.PROCESS(非绑定的)此外一个也许常用的属性是线程的优先级,它存放在结构sched_param中用函数Pthread_attr_getschedparam和函数pthread_attr_setschedparam进行存放,一般说来我们总是先取优先级,对取得的值修改后再存放回去4线程的数据解决和进程相比,线程的最大优点之一是数据的共享性各个进程共享父进程处沿袭的数据段,可以方便的获得、修改数据但这也给多线程编程带来了许多问题我们必须当心有多个不同的进程访问相同的变量许多函数是不可重入的,即同时不能运营一个函数的多个拷贝(除非使用不同的数据段)在函数中声明的静态变量经常带来问题,函数的返回值也会有问题互斥锁互斥锁用来保证一段时间内只有一个线程在执行一段代码必要性显而易见:假设各个线程向同一个文献顺序写入数据最后得到的结果一定是劫难性的条件变量互斥锁一个明显的缺陷是它只有两种状态:锁定和非锁定而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法填补了互斥锁的局限性,它常和互斥锁一起使用使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化信号量信号量既可以作为二值计数器即01也可以作为资源计数器.信号量本质上是一个非负的整数计数器它被用来控制对公共资源的访问当公共资源增长时,调用函数sem_post增长信号量只有当信号量值大于时才干使用公共资源,使用后,函数sem_wait减少信号量函数sem_trywait和函数pthread_mutex_try1ock起同样的作用,它是函数sem_wait的非阻塞版本实验内容:线程函数编译时需要添加特殊编译选项:gcc火.c-Ipthread-o
1、完毕教材上thread.c的例子,想一下每次执行时结果相同吗,为什么?答:每个线程的运营和结束时无序的、独立与并行的实验代码/*thread.c*/#includestdio.h#includesIdlib.h#includepthread.h#defineTHREAD_NUMBER3/*线程数*/#defineREPEAT_NUMBER5/*每个线程中的小任务数*/#defineDELaY_TIME_LEVELS
6.0/*小任务之间的最大时间间隔*/void*thrd_funcvoid*arg〃指针好乱,这里看不懂定义了什么,求解择〃定义「一个返回值为指向空类型的指针的函数,该函数的参数为一个指针/*线程函数例程*/1ntthrd.num=intarg;//这个是赋值吗看不懂,求解释//定义了一个整型参数,取值为argintdelay_time=0;intcount=0;printfThread%disstarting\nthrd_num;forcount=0;countREPEAT_NUMBER;count++《delay_time=intrand*DELAY_TIME_LEVELS/RAND_MAX+1;Printf\tThread%d:job%ddeIay=%d\nthrd_numcountdeIay_time;sleepde1ay_time;〃暂停?秒//暂停随机秒//\t输出一个Tab占8列〃输出格式Threadthrd_num:jobcountdelay=deIay_time【可车printfMThread%dfinished\nthrd_num〃输出格式Threadthrd_numfinished回车pthread_exitNULL;intmainvoid{pthread_tthread[THREAD_NUMBER]//定义了一个类型为Pthread」的数组,数组元素的个数为3intno=0res;void*thrd_ret;//这句什么意思求解释〃定义了一个指针,指向哪里后面的程序里有srandtimeNULL;〃这句什么意思?求解释〃用系统时间计算一个随机数forno=0;noTHREAD_NUMBER;no++{/*创建多线程*/res=pthread_createthread[no].NULLthrd_func-void*no;//thread[no]线程标记符//pthread_create函数的参数含义请看书ifres!=0〃创建线程犯错时res=错误码printfCreatethread%dfailed\n•no;exitres;//上面的不是退出进程,而是判断pthread_create函数是否成功执行PrintfCreatetreadssuccess\nWaitingforthreadstofinish...\n〃假如上面没退出进程,则创建线程成功forno=0;noTHREAD_NUMBEK;no++{/*等待线程结束*/res=pthread_jointhread[no]rthrd_ret;//thread[no]线程标记符,此例总共有thread[O]thread[l]fIhread
[2]3个线程〃清看书上pthread_join函数的参数含义.ifIres//res=OBb挂起线程成功〃res=0时,说明pthread_Join函数执行成功printfThread%djoined\nno;e1seprintfThread%djoinfailed\nno;}reiurn
02、完毕教材上thread_mutex.c例,查看运营情况和上例比较有何不同想一下为什么会出现这种差异?答这里3个线程之间的运营顺序跟创建线程的顺序相同includestdio.hincludestd1ib.hincIudepthread.hdefineTHREAD_NUM3/*线程数*/#defineREPEAT_NUM3/*悠个线程的小任务数*/#defineDELAY_TIME_LEVELS
6.0/*小任务之间的最大时间间隔*/pthread_mutex_tmutex;void*thrd_funcvoid*arg{intthrd_num=intarg;intdelay_time=0count=0intres/*互斥锁上锁*/res=pthread_mutexJockmutex;ifres{printfThread%dlockfailed\nthrd_num pthrcad_exitNULL;}printfThread%disstarting\n.thrd_num;forcount=0;CountREPEAT_NUM count++{delay_time=intrand*DELAY_TIME_LEVELS/RAND.MAX+1;sleepdeIay_timc;printf\tThread%d:job%ddelay=%d\nthrd_numcountdelay_time;printfThread%dfinished\nzthrd_num;pthread_mutex_unlockmutex;Pthread_exitNULL;}intmainvoid{pthread_tthread[THREAD_NUM];intno=0res void♦thrd_ret;srandtimeNULL;/*互斥锁初始化*/pthrcad_mutex_initmutexNULL;forno=0;noTHREAD_NUM;no++{res=pthread_createthread[no]NULLthrd_funifres!=0{printfCreatethread%dfaiIed\nno;exitres;}printfCreatetreadssuccess\nWaitingforthreadsforno=0;noTHREAD_NUM;no++{res=pthread_ointhread[no]thrd_ret;if!res{PrintfThread%djoined\n.no}eIse{oprintfThread%djoinfailed\nno;}}pthread_mutex_destroymutex;return0;
3、完毕教材上thread_attr.c例子,并运营查看结果,然后和前面两个例子比较查看系统资源的差异答:理论中线程在运营结束后就回收系统资源,并释放内存程序代码#includestdio.hincludestd1ib.hinc1udepthread.hdefineREPEAT_NUMBER3/*线程中的小任务数♦/defineDELAY_TIME_LEVELS
10.0/*小任务之间的最大时间间隔*/intfinish_f1ag=0;void*thrd_funcvoid*argintdelay_time=0;intcount=0;PrintfThreadisstarting\n;forcount=0;countREPEAT_NUMBER;count++{delay_time=intrand*DELAY_TIME_LEVELS/RAND_MAX+1;sleep1elay_time;printf\tThread:job%dde1ay=%d\ncountzdelay_time;}printfThreadfinished\n;finish_flag=1;pthread_exitNULL;。