嵌入式第8章 多线程编程.ppt
文本预览下载声明
信号量线程控制 头文件 semaphore.h 创建信号量 int sem_init(sem_t *sem, int pshared, unsigned int value) value为信号量的初值,pshared表示是否为多进程共享而不仅仅是用于一个进程。 LinuxThreads没有实现多进程共享信号量,因此所有非0值的pshared输入都将使sem_init()返回-1,且置errno为ENOSYS。 销毁信号量 sem_destroy(sem_t *sem) 获取信号量值 sem_getvalue(sem_t *sem) 信号量线程控制 申请一个信号资源 sem_wait( sem_t *sem ) 被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。 释放一个信号资源 sem_post( sem_t *sem ) 用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞 测试一个资源是否可用 sem_trywait ( sem_t *sem )是 举例:thread_sem.c 第8章 多线程编程 8.1 Linux线程概述 8.2 Linux线程编程 8.3 线程的并发访问 8.1 线程概述 线程:在一个程序中的多个执行路线就叫做线程(thread),更准确的定义是:线程是一个进程内部的一个控制序列。 线程(thread)技术早在60年代就被提出,但真正的应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者。 Linux线程技术的发展: Linux线程技术的发展 在Linux2.2内核中,并不存在真正意义上的线程。当时Linux中常用的线程pthread实际上是通过进程来模拟的,也就是说Linux中的线程也是通过fork()创建的“轻”进程,并且线程的个数也很有限,最多只能有4096个进程/线程同时运行。 Linux2.4内核消除了这个线程个数的限制,并且允许在系统运行中动态地调整进程数上限。 在Linux 内核2.6之前的版本中,进程是最主要的处理调度单元,并没支持内核线程机制。Linux系统在1996年第一次获得线程的支持,当时所使用的函数库被称为LinuxThread。 Linux线程技术的发展 (2) 为了改善LinuxThread问题,出现根据新内核机制重新编写线程库的问题。许多项目在研究如何改善Linux对线程的支持,其中两个最有竞争力的有由IBM主导的新一代POSIX线程库(Next Generation POSIX Threads,简称为NGPT)和由Red Hat主导的本地化POSIX线程库 (Native POSIX Thread Library,简称为NPTL)。 NGPT项目在2002年启动,但为了避免出现有多个Linux线程标准,所以在2003年停止该项目。与此同时NPTL问世,最早在Red Hat Linux9中被支持,现在已经成为GNU C函数库的一部分,同时也成为Linux线程的标准。 线程与进程 前面已经提到,进程是系统中程序执行和资源分配的基本单位。每个进程都拥有自己的数据段、代码段和堆栈段,这就造成了进程在进行切换等操作时都需要有比较复杂的上下文切换等动作。为了进一步减少处理机的空转时间,支持多处理器以及减少上下文切换开销,进程在演化中出现了另一个概念——线程。它是进程内独立的一条运行路线,处理器调度的最小单元,也可以称为轻量级进程。线程可以对进程的内存空间和资源进行访问,并与同一进程中的其他线程共享。因此,线程的上下文切换的开销比创建进程小很多。 同进程一样,线程也将相关的执行状态和存储变量放在线程控制表内。一个进程可以有多个线程,也就是有多个线程控制表及堆栈寄存器,但却共享一个用户地址空间。要注意的是,由于线程共享了进程的资源和地址空间,因此,任何线程对系统资源的操作都会给其他线程带来影响。由此可知,多线程中的同步非常重要。 线程概述(2) 线程拥有自己的栈(有自己的局部变量),但与线程共享全局变量、文件描述 符、信号处理函数和当前的目录状态。 线程的优点 线程和进程相比,是一种非常“节俭”的多任务操作方式。在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段,堆栈段和数据段,这是一种“昂贵”的多任务工作方式 运行于一个进程中的多线程,他们之间使用相同的地址空间,而且线程间彼此切换所需的时间也远远小于进程间切换所需的时间,据统计,一个进程的开销大约是一个线程开销的30倍左右。 线程的优点 多线程之间方便的通信机制。对不同进程来说,他们具有独立的数据空间,要进行数据的传递只能通过进程间通信的方式,这种方式不仅费时,而
显示全部