您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 能源与动力工程 > chap 5 Linux 多线程编程
Linux系统编程第5章多线程编程戴瑾daijin.njujl@gmail.com南大金陵学院信息科学与工程系2主要内容线程/进程基本概念线程管理线程属性控制线程通信3进程及线程基本定义进程(process)处于执行期的程序及其所包含资源的总称程序:可执行程序代码资源:打开文件、挂起信号、地址空间、数据段等线程(thread)进程中活动的对象有独立的程序计数器、进程栈及一组进程寄存器节省主存、减少管理开销、快速切换进程/线程基本概念4进程与线程进程资源分配单位进程的上下文组成进程控制块PCB:包括进程的编号、状态、优先级以及正文段和数据段中数据分布的大概情况正文段(textsegment):存放该进程的可执行代码数据段(datasegment):存放进程静态产生的数据结构用户堆栈(stack)线程CPU调度基本单位进程/线程基本概念5进程执行状态相关信息进程ID、进程组ID、用户ID和组ID工作环境(Environment)工作目录(Workingdirectory)程序指令(Programinstructions)寄存器(Registers)栈(Stack)堆(Heap)文件描述符(Filedescriptors)信号(Signalactions)共享库(Sharedlibraries)进程间通信手段(Inter-processcommunicationtools)进程/线程基本概念6线程与进程的关系包含在进程中的一种实体有自己的运行线索,可完成特定任务可与其他线程共享进程中的共享变量及部分环境可通过相互之间协同来完成进程所要完成的任务线程维护的信息堆栈指针寄存器调度属性信号线程私有数据进程/线程基本概念7线程的基本特点是进程的一个实体,可作为系统独立调度和分派的基本单位有不同的状态,有控制线程的各种原语,包括创建和撤销线程等不拥有系统资源(只拥有从属进程的全部资源,资源是分配给进程)一个进程中的多个线程可并发执行进程中创建的线程可执行同一程序的不同部分也可以执行相同代码系统开销小、切换快进程的多个线程都在进程的地址空间活动,共享全局变量进程/线程基本概念8线程之间的共性特征同一进程中的多个线程共享该进程的虚拟空间进程代码段进程的公有数据利用这些共享的数据,线程很容易的实现相互通讯进程打开的文件描述符信号的处理器进程的当前目录和进程用户ID与进程组ID说明对不同进程来说,具有独立的数据空间,数据传递只能通过通信的方式进行,这种方式费时而不方便进程/线程基本概念9线程的个性特征线程是实现并发的必要条件线程ID每个线程都有自己唯一的线程ID寄存器组的值创建线程时,须将原有线程的寄存器集合的状态保存线程的堆栈线程必须拥有自己的函数堆栈,使得函数调用可以正常执行,不受其他线程的影响错误返回码不同线程应该拥有自己的错误返回码变量线程的信号屏蔽码线程的信号屏蔽码应由线程自己管理,但所有线程都共享同样的信号处理器线程的优先级进程/线程基本概念10线程组成员之间的关系进程/线程基本概念11用户线程用户线程存在于用户空间,通过线程库来实现线程库提供对线程的创建、调度和管理的支持,而无须内核支持内核并不知道用户级线程,所有线程的创建和调度都在用户空间内进行,无须内核干预用户级线程的调度以进程为单位优点同一进程内的线程切换不需要转换到内核,调度算法是进程专用的缺点系统调度阻塞问题,不能充分利用多处理器进程/线程基本概念12内核线程由操作系统直接支持,内核在其空间内执行线程的创建、调度和管理由于线程管理由操作系统完成,因此内核线程的创建和管理要慢于用户线程的创建和管理优点支持多处理器,支持用户进程中的多线程、内核线程切换的速度快缺点对用户的线程切换来说,系统开销大进程/线程基本概念13线程-多线程模型多对一模型将许多用户级线程映射到一个内核线程线程管理在用户空间进行,效率较高处理机调度的单位仍然是进程缺点如果一个线程执行了阻塞系统调用,那么整个进程就会阻塞因为任何时刻只有一个线程访问内核,多个线程不能并行运行在多处理器上说明在不支持内核级线程的操作系统上所实现的用户级线程库也使用多对一模型进程/线程基本概念14线程-多线程模型一对一模型将每个用户线程映射到一个内核线程在一个线程执行阻塞时,允许另一个线程继续执行允许多个线程运行在多处理机系统上提供比多对一模型更好的并发功能缺点创建一个用户线程就需要创建一个相应内核线程创建内核线程的开销会影响应用程序的性能,这种模型的绝大多数实现限制系统所支持的线程数量进程/线程基本概念15线程-多线程模型多对多模型多路复用许多用户级线程到同样数量或更小数量的内核线程上内核线程的数量可能与特定应用程序或特定机器有关克服前两种模型的缺点开发人员可以创建任意多的必要的线程,并且相应内核线程能在多处理器系统上并行运行当一个线程执行阻塞系统调用时,内核能调度另一个线程来执行进程/线程基本概念16主要内容线程/进程基本概念线程管理线程属性控制线程通信17pthread背景早期各硬件厂商主要使用私有版本线程库,实现差异非常大,开发者难于开发可移植的线程应用为能够最大限度的提高线程的性能,需要一个标准的编程接口对于UNIX系统,IEEEPOSIX1003.1c标准(1995)定义了这样的接口遵从该标准实现的线程被称做POSIX线程,或pthreadspthreads定义了一套C语言编程接口和函数调用包括一个pthread.h头文件和一个线程库线程管理18pthread介绍基于POSIX标准的线程编程接口包括一个pthread.h头文件和一个线程库编译方法gcc–g**.c-o***–lpthread功能线程管理支持线程创建/删除、分离/联合,设置/查询线程属性互斥处理同步,称为“mutex”创建/销毁、加锁/解锁互斥量,设置/修改互斥量属性条件变量支持基于共享互斥量的线程间通信建立/销毁、等待/触发特定条件变量,设置/查询条件变量属性线程管理19pthread类型线程管理支持线程创建、分离、联合等,还包括线程属性的设置/查询互斥处理同步,称为“mutex”提供创建、销毁、加锁和解锁互斥量也包括补充的修改互斥量属性功能,并用它去设置或者修改与互斥相关的属性条件变量支持基于共享互斥量的线程间通信,以开发者的特定条件变量为基础。包括基于特定条件变量的建立、销毁、等待和信号触发设置/查询条件变量属性的功能也包括在内线程管理20pthread变量类型的命名规则前缀形式功能组pthread_线程自身及其他子例程pthread_attr_线程属性对象pthread_mutex_互斥变量pthread_mutexattr_互斥属性对象pthread_cond_条件变量pthread_condattr_条件属性对象pthread_key_特定线程数据键线程管理21线程管理线程创建线程终止线程终止时的资源清理说明头文件#includepthread.h线程管理22线程创建函数原型intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);参数说明thread:要创建的线程id指针attr:创建线程时的线程属性v(*start_routine)(void*):返回值是void*类型的指针函数arg:start_routine的参数返回值成功返回0失败返回错误编号EAGAIN:表示系统限制创建新的线程,如线程数目过多EINVAL:代表线程属性值非法线程管理23线程示例#includepthread.h#includestdio.hvoid*create(void*arg){printf(newthreadcreated.....);}intmain(intargc,char*argv[]){pthread_ttidp;interror;error=pthread_create(&tidp,NULL,create,NULL);if(error!=0){printf(pthread_createisnotcreated...);return-1;}printf(prthread_createiscreated...);return0;}线程管理24pthread_create()的参数传递问题基本问题intpthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg);仅允许传递一个参数给线程待执行的函数如何传递多个参数解决途径构造一个包含所有参数的结构,将结构指针作为参数传递给pthread_create()所有参数必须利用(void*)来传递线程管理25pthread_create()参数传递—错误示例向新建线程传入线程号信息线程管理26pthread_create()参数传递—错误示例错误示例线程管理27pthread_create()参数传递—错误示例运行结果线程管理28pthread_create()参数传递—正确示例1传递一个简单整数线程管理29pthread_create()参数传递—正确示例1传递一个简单整数线程管理30pthread_create()参数传递—正确示例1运行结果线程管理31pthread_create()参数传递—正确示例2向新建线程同时传入线程号/消息/线程号总和线程管理32pthread_create()参数传递—正确示例2向新建线程同时传入线程号/消息/线程号总和线程管理33pthread_create()参数传递—正确示例2向新建线程同时传入线程号/消息/线程号总和线程管理34pthread_create()参数传递—正确示例2向新建线程同时传入线程号/消息/线程号总和线程管理35pthread_create()参数传递—正确示例2向新建线程同时传入线程号/消息/线程号总和线程管理36线程ID的访问获取线程自身的id函数原型pthread_tpthread_self(void);返回值调用线程的线程id比较线程ID函数原型intpthread_equal(pthread_ttid1,pthread_ttid2);参数tid1:线程1的idtid2:线程2的id返回值相等返回非0值否则返回0线程管理37线程终止正常终止方法1:线程自己调用pthread_exit()voidpthread_exit(void*rval_ptr);rval_ptr:线程退出返回的指针,进程中其他线程可调用pthread_join()访问到该指针方法2:在线程函数执行return非正常终止其它线程的干预自身运行出错线程管理38线程执行轨迹同步方式(非分离状态)等待新创建线程结束只有当pthread_join()函数返回时,创建的线程才算终止,才可释放自己占用的系统资源异步方式(分离状态)未被其他线程等待,自己运行结束即可终止线程并释放系统资源线程管理39线程同步终止函数原型intpthread_join(pthread_tthread,void**rval_ptr);功能调用者将挂起并等待新进程终止当新线程调用pthread_exit()退出或者return时,进程中的其他线程可通过pthread_join()获得进程的退出状态使用约束一个新线程仅仅允许一个线程使用该函数等待它终止被等待线程应处于可join状态,即非DETACHED状
本文标题:chap 5 Linux 多线程编程
链接地址:https://www.777doc.com/doc-3871760 .html