版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
4.8线程
(一)问题的提出进程的引入使操作系统得以完成对并发执行的多道程序动态特征的描述和资源共享的管理,因而进程既是调度的基本单位又是资源分配的基本单位。进程所具有的这两个特点构成了程序并发执行的基础,但同时又导致进程切换过程中由于进程映像过大而带来的时空开销。因此,如果系统中创建的进程过多,或进程切换的频率过高,则会使系统效率下降,限制了并发度的进一步提高。进程切换所带来的庞大开销是因为进程与资源分配有关,操作系统如何降低进程切换所需要的时空开销呢?比如野战军作战略转移时,所有辎重都要随身携带,速度自然很慢。但是当部队要抢占山头时所采取的办法是卸下辎重,只带轻武器以急行军方式跑步前进,速度自然就会快很多。那么,操作系统是否也可以将调度的基本单位改成一种只用于调度执行而不涉及资源分配的单位?这个单位就是“线程”。——减小进程上下文切换开销及更好地支持SMP(对称多处理)1(二)线程及其特征线程是调度执行的基本单位;线程不是资源分配的基本单位;线程从属于某个进程,是该进程的某个执行路线。因此,也将进程称为重型进程,线程称为轻型进程。线程是进程中的一个相对独立的可执行单元。一个进程中至少包含一个线程。由于同一进程内的线程之间涉及资源共享,所以需要同步机制来实现进程内多线程之间的通信。与进程类似,线程还可以创建其它线程,线程也有生命周期,也有状态的变化。2(三)线程与进程的主要区别与联系调度与资源分配 在引入线程的操作系统中,线程是调度和指派的基本单位,而进程是资源的拥有单位。在同一进程中,线程的切换不会引起进程的切换;而在不同的进程中进行线程的切换,比如从一个进程中的线程切换到另一个进程中的线程时,将会引起进程的切换。线程不拥有资源,但可以访问它所在的进程的资源,从而获得系统资源。并发性 引入线程的操作系统具有更好的并发性。系统开销 进程切换时有很大的时空开销,而线程切换时只需要保存和设置少量的寄存器内容,时空开销很小。另外,由于同一进程内的多个线程共享进程的同一地址空间,因此,多个线程之间的同步与通信也非常容易实现,甚至不需要操作系统内核的干预。在一个进程内使用多线程的优点主要在于创建线程的工作量要比创建进程的工作量小不涉及资源分配,不同线程之间的切换比进程之间的切换要快。
3(四)
线程的状态与线程控制块与进程类似,线程也是一个动态的概念,也有一个从创建到消亡的过程,它也具有以下几个基本状态:新建态就绪态:具备执行条件,等待调度。运行态:正占有CPU处于运行中。阻塞态:等待某个事件发生。结束态:线程结束执行,释放其寄存器上下文和堆栈的内容。线程使用线程控制块TCB(ThreadCotrolBlock)来描述。线程由与其相关的堆栈、寄存器和线程控制块TCB组成。寄存器可以用来存储线程内的局部变量,但是不能存储其它线程的局部变量。线程的控制原语包括线程创建、线程终止、线程阻塞等等。
4(五)线程的分类1.用户级线程用户级线程ULT(User-LevelThread)由用户程序创建,并由用户程序对其进行调度和管理。操作系统内核并不知道有用户级线程的存在,因而用户级线程与内核无关。我们也称之为“纯ULT方法”。MS-DOS、Unix属于这种方法。其优点在于:应用程序中的线程转换开销比内核级的开销要小得多。(开销小)线程的调度算法与操作系统的调度算法无关。(算法灵活)用户级线程方法可以适用于任何操作系统,因为它与内核无关。(高适应性)其缺点在于:当进程中某线程执行一个系统调用而被阻塞时,会导致本进程的其它线程也阻塞。在纯ULT方式下,多线程不便利用多处理器,因为每次只有一个进程的一个线程在一个CPU上运行。52.内核级线程内核级线程KLT(Kernel-LevelThread)中,所有线程的创建、调度、管理都由操作系统内核负责。一个用户进程可以按多线程方式编写程序,当它被提交给多线程操作系统运行时,内核为它创建一个进程和一个线程,线程在运行中还可以创建新的线程。我们称之为“纯KLT方法”。WindowsNT属于此类。其优点在于:内核可以调度一个进程中的多个线程,使其同时在多个处理器上并发运行,从而提高运行的速度和效率。当进程中的一个线程被阻塞时,该进程中的其它线程仍可运行。内核本身也可以用线程的方式实现。其缺点在于:同一进程中的线程切换要有两次态的转换(用户态→内核态→用户态),因为线程的调度运行在内核态,而应用程序运行在用户态。6(六)线程举例1.Linux线程系统调用⑴.创建线程格式:
intpthread_create(pthread_t*thread,pthread_attr_t*attr, void*(*start_routine)(void*),void*arg)参数说明:thread——返回创建的线程标识符ID,是个指向线程标识符的指针;attr——设置线程的属性,如果使用NULL则表示为系统默认属性;start_routine——线程执行函数的地址,该函数必须具有void*返回值;arg——线程执行函数的参数,如果不带参数则可以使用NULL。返回值:成功返回0
出错则返回错误码注:①.该系统调用调用clone函数来创建线程。②.由于线程没有自己的存储空间,所以,它所执行的函数需要在创建它的进程中加以定义。
71.Linux线程系统调用⑵.线程终止格式:intpthread_exit(void*retval) 参数说明:retval——传递给创建它的父线程的终止信息。功能:终止一个线程。返回值:成功返回0
出错则返回错误码8大家有疑问的,可以询问和交流可以互相讨论下,但要小声点91.Linux线程系统调用⑶.等待线程终止格式: intpthread_join(pthread_tth,void**thread_return)参数说明:th——被等待的线程标识符,*thread_return——用户定义的指针,它可以用来存储被等待线程的终止信息。类似于wait([int*stat_addr,]0)中的*stat_addr。如果不需要取终止信息则可使用NULL。功能:回收终止的线程,类似于回收进程waitpid()。调用它的函数将一直等待到被等待的线程结束为止。当函数返回时,被等待线程的资源被收回。返回值:成功返回0
出错则返回错误码所用头文件:#include<pthread.h>102.Linux线程举例[例]在主函数中创建一个线程,其功能是循环输出3次“Thisisthesecondpthread.”;主线程也循环输出3次“Thisisthemainpthread.”,观察并分析它们的执行过程。源程序清单,文件名:pthread.c#include<stdio.h>#include<pthread.h> //线程所用头函数
/*定义线程的执行函数*/voidthread(void) //必须使用void作为返回类型 {inti;for(i=0;i<3;i++){ printf(“Thisisthesecondpthread.\n”);//显示自己是子线程
sleep(1);}}11main(){/*定义线程内部标识*/pthread_tthreadid;inti,ret;
/*创建一个子线程并指定执行函数,函数不带参数*/ret=pthread_create(&threadid,NULL,(void*)thread,NULL);if(ret!=0){printf("Createpthreaderror!\n");exit(1);}/*主线程循环输出3次*/for(i=0;i<3;i++) {printf("Thisisthemainpthread.\n"); sleep(1);}pthread_join(threadid,NULL); //等待子线程结束
exit(0);}12带有线程的源程序在进行编译时需要使用参数-lpthread:
gcc-lpthread–o目标文件名源文件名
编译和运行该程序后的结果为:由上述输出结果可以看出,当线程作为调度的基本单位时,创建的子线程连同主线程共形成两个线程被操作系统调度,因而产生以上类似于进程随机调度的运行结果。133.多线程举例
[例]定义一个多线程标识符数组,然后创建多个线程,每个线程执行的程序都是显示该线程标识符及其下标值。主线程则等待每个线程终止,显示结束提示符后结束运行。设创建5个子线程。
程序清单:文件名multhread.c#include<pthread.h>#include<stdio.h>#defineMAXTHREAD5//定义多线程标识符数组元素个数void*threaf_fuction(void*arg)
//定义线程执行函数{ printf(arg); printf("\n");}14/*主线程*/main(){ inttid; pthread_tthreads[MAXTHREAD]; //定义多线程标识符数组 /*定义线程执行函数的参数*/
charmessage[][10]={"thread1","thread2","thread3","thread4","thread5"};
/*循环创建5个子线程*/ inti; for(i=0;i<5;i++) {/*创建子线程并指定执行函数及参数*/tid=pthread_create(&threads[i],NULL,threaf_fuction,message[i]); if(tid!=0) { perror("Threadcreationfailed"); exit(1); }}15
/*主线程*/ for(i=0;i<5;i++) pthread_join(threads[i],NULL);//等待5个子线程终止
printf("Allthreadfinished.\n"); //输出结束提示
exit(0); }16(七)Linux多线程同步下的信号量Mutex:
变量定义:
pthread_mutex_tmut;
初始化:
pthread_mutex_init(&mut,NULL);
进入加锁:
pthread_mutex_lock(&mut);
退出解锁:
pthread_mutex_unlock(&mut);
17voidthread1(){pthread_mutex_lock(&count_lock);printf("thethread1enterthecirticalsection..\n"); sleep(2);printf("thethread1exitthecirticalsection..\n");pthread_mutex_unlock(&count_lock);pthread_exit(NULL);}voidthread2(){pthread_mutex_lock(&count_lock)printf("thethread2enterthecirticalsection..\n"); sleep(2);printf("thethread2exitthecirticalsection..\n");pthread_mutex_unlock(&count_lock);pthread_exit(NULL);}Linux下利用互斥锁实现线程互斥:#include<stdlib.h>#include<unistd.h>#include
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年上半年教师资格考试《小学教育教学知识与能力》真题及答案解析
- 2025年教师资格证考试试题真题及答案
- 2026浙江省烟草招聘考试(行政职业能力测验)历年参考题库含答案详解3卷
- 2026浙江教师职称考试(教育教学能力与综合素质)历年参考题库含答案详解3卷
- 2026法院司法辅助人员-法检系统书记员考试历年参考题库含答案详解3卷
- 2026河南机关事业单位工勤技能岗位等级考试(堤灌维护工·中级/四级)历年参考题库含答案详解2卷
- 2026河北省机关事业单位工人技能等级考试(加工制冷工·中级)历年参考题库含答案详解2卷
- 2026河北机关事业单位工人技能等级考试(计算机操作员·高级)历年参考题库含答案详解2卷
- 2026江西省高职院校单独招生考试(职业适应性测试)历年参考题库含答案详解3卷
- 2026江西省住院医师规范化培训结业理论考核(临床病理科)历年参考题库含答案详解3卷
- Java程序设计及应用-增量式项目驱动一体化教程(实验篇)
- 2026年南阳市中心医院公开招聘专业技术人员310人笔试参考题库及答案详解
- 2026-2030中国大型轮式拖拉机行业应用规模分析及发展态势展望报告
- 2026中小学教资科目一二高频考点必背-考前速记通关
- 人工繁育动物放归野化训练指导手册
- 雨课堂学堂在线学堂云《教育社会学(清华)》单元测试考核答案
- 2026年海南省重点学校初一新生入学分班考试试题及答案
- 生物竞赛介绍课件教学
- 肩关节镜体位摆放
- 新疆兵团考试真题及答案
- 2025内蒙古生态环境科学研究院有限公司招聘2人笔试备考试题附答案
评论
0/150
提交评论