多线程编程.pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《多线程编程.pdf》由会员分享,可在线阅读,更多相关《多线程编程.pdf(48页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、多线程编程2007-09-062 0 0 5BAIDU CONFIDENTIAL内容提要 多线程编程简介 POSIX多线程使用 Linux线程实现 多线程编程与调试2 0 0 5BAIDU CONFIDENTIAL什么是多线程?一个进程内部的多个可并发执行的任务实体。多线程之间共享数据 抽象概念2 0 0 5BAIDU CONFIDENTIAL为什么使用多线程?提高系统的并发性 多cpu:多个线程在不同cpu上并发执行 单cpu:IO和cpu计算等的并行 提高程序的响应效率,特别是GUI程序 软件功能划分清晰2 0 0 5BAIDU CONFIDENTIAL多线程而不是多进程?线程相对与进程的
2、优点 性能好。线程启动、切换的开销都小于进程,内存占用也小于进程 共享数据。线程间数据直接可见,进程间需要使用IPC机制 方便移植。遵循POSIX标准2 0 0 5BAIDU CONFIDENTIALPOSIX线程 Portable Operating System Interface 遵循IEEE POSIX 1003.1c-1995标准 定义了线程API和行为 业界支持最广泛 多种实现:LinuxThreads、NGPT、NPTL 多种OS:Linux、Solaris、IRIX、AIX but Win32&OS/22 0 0 5BAIDU CONFIDENTIALPOSIX线程函数 POS
3、IX线程函数提供以下几类功能:线程的创建、终止、取消 线程属性控制 线程同步控制 线程专有数据的维护2 0 0 5BAIDU CONFIDENTIAL线程创建 int pthread_create(pthread_t*thread,pthread_attr_t*attr,void*(*start_routine)(void*),void*arg);启动一个新线程,线程执行体为start_routine函数 调用之后马上返回。创建成功返回0,失败则为非02 0 0 5BAIDU CONFIDENTIAL线程终止 线程执行体函数退出,线程就终止了 通过调用下面的函数退出:void pthread_
4、exit(void*retval);2 0 0 5BAIDU CONFIDENTIAL线程分离状态 非分离状态(缺省)当该状态的线程正常执行退出时,并不释放自身占用资源(线程描述体、线程栈)需要其他线程执行如下函数来join该线程:int pthread_join(pthread_t th,void*thread_return);调用pthread_join()的线程阻塞直到待join的线程退出,并释放退出线程占用的资源。2 0 0 5BAIDU CONFIDENTIAL线程分离状态(续)分离状态线程执行退出,自动释放其占用的资源。可能的问题:线程在pthread_create()调用返回之前
5、就退出,可能会导致返回错误的线程号。解决方法:线程开始时睡眠一小段时间2 0 0 5BAIDU CONFIDENTIAL简单代码实例void*run(void*arg)for(;)sleep(1);int main(int argc,char*argv)pthread_t tid;pthread_create(&tid,NULL,run,NULL);pthread_join(tid,NULL);return 0;2 0 0 5BAIDU CONFIDENTIAL常见问题:exit()出core 原因 按标准C的定义,exit函数需要把STDIO打开的句柄写buffer里的数据写下去,并释放打开
6、的句柄 一个进程调用exit两次,其行为是未定义的。我们可以认为exit不是一个线程安全的函数 解决方法 协调所有线程友好的退出 把exit()替换为向本进程发SIGKILL2 0 0 5BAIDU CONFIDENTIAL线程同步 线程同步机制:mutex,互斥锁 condition variable,条件变量 semaphore,信号量2 0 0 5BAIDU CONFIDENTIAL锁(mutex)与临界区 共享变量操作需要临界区,使多个线程对共享变量的访问串行化 不是对所有的共享变量操作都需要临界区,那些有竞争条件(race condition)的共享变量操作才需要临界区 锁是一种进程
7、(线程)间同步的协议,锁这个概念(mutual exclusion)很好解决了临界区问题2 0 0 5BAIDU CONFIDENTIALmutex加锁和解锁 加锁:pthread_mutex_lock(&mutex_var);当前mutex_var没有被其他线程加锁,则对其加锁,否则阻塞直到其他线程解锁,并再次尝试加锁 解锁:pthread_mutex_unlock(&mutex_var);2 0 0 5BAIDU CONFIDENTIAL线程锁的开销 锁操作开销比算数运算(指各种整数及浮点运算)慢得多,但比磁盘和网络I/O快得多 开销源于两个方面内核和线程库对锁的管理操作(如排队等)锁操作
8、引起的频繁进程/线程切换2 0 0 5BAIDU CONFIDENTIAL线程锁的粒度 纵向:被锁的区域(临界区)有多少操作,执行一次要多少时间。它描述的是多大规模的操作被串行。横向:就是一个锁锁住了多少资源。它描述的是有多少资源被串行访问。锁的粒度越小越有利于提高程序的并发度,但锁操作本身的开销越大。2 0 0 5BAIDU CONFIDENTIAL原子操作 原子操作是硬件提供的,不可中断指令单处理器下,单指令操作是原子操作多处理架构(SMP或CMP)下,多条指令可以同时执行,单指令本身不能保证原子操作 原子操作与线程锁都是解决临界区问题的方式,不同在于锁是软件级的,原子操作是硬件级的。2
9、0 0 5BAIDU CONFIDENTIAL常见问题:赋值是否需要加锁 共享变量简单赋值操作的并发问题 有一个共享变量status,有一个线程会修改status(修改为简单赋值,无中间值),其它线程只读不改。共享变量status必须是可以原子读和原子写 少于等于一个字长,正常的字节对齐 无竞争条件,因而不需要临界区,无需加锁2 0 0 5BAIDU CONFIDENTIAL线程安全的函数 在ANSI C开发时没有考虑到线程,因此C标准库函数有一些不是线程安全的:内部使用静态变量并作为返回值的函数,例如gmtime在一系列调用之间要求静态环境的函数,例如strtok pthreads定义了现存
10、函数的变体,相应函数名结尾加后缀_r,这些变体是线程安全的2 0 0 5BAIDU CONFIDENTIAL条件变量 pthread_cond_*系列函数 线程可以在条件变量上被阻塞和唤醒。无计数(与信号量不同),阻塞和唤醒需要显式进行,条件判断由用户自定义。必须和mutex结合使用,保证判断和阻塞的原子性。2 0 0 5BAIDU CONFIDENTIAL条件变量的创建和销毁 条件变量类型:pthread_cond_t 初始化方法有两种:pthread_cond_init(&cont_var,NULL);cond_var=PTHREAD_COND_INITIALIZER;销毁:pthread
11、_cond_destroy(&cont_var);2 0 0 5BAIDU CONFIDENTIAL阻塞和唤醒 阻塞于条件变量 pthread_cond_wait();pthread_cond_timedwait();/带超时 唤醒条件变量上的阻塞线程 pthread_cond_signal();pthread_cond_broadcast();/唤醒所有2 0 0 5BAIDU CONFIDENTIAL阻塞于条件变量 实例代码pthread_mutex_lock(&mutex_var);while(count=0)pthread_cond_wait(&cond_var,&mutex_var)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 多线程 编程
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内