笔记
第四章 并发编程
并行计算导论
并行计算是一种计算方法,通过使用多个执行并行算法的处理器相较串行计算更快地解决问题。
顺序算法与并行算法
- 顺序算法
begin
step_1;
step_2;
...
step_n;
end
// next step
- 并行算法
cobegin
task_1;
task_2;
...
task_n;
coend
// next step
并行性与开发性
- 并行性
在理想情况下,并行算法中的所有任务都应该同时实时执行。然而,真正的并行执行只能在有多个处理组件的系统中实现,比如多处理器或多核系统。
- 并发性
在单CPU系统中,并发性所说通过多任务处理来实现的。
线程
线程的原理
一个操作系统(OS)包含许多并发进程“在进程模型中,进程是独立的执行单元。所有进程均在内核模式或用户模式下执行。在内核模式下,各进程在唯一地址空间上执行,与其他进程是分开的。虽然每个进程都是一个独立的单元,但是它只有一个执行路径。当某进 程必须等待某事件时,例如I/O完成事件,它就会暂停,整个进程会停止执行匸线程是某进程同一地址空间上的独立执行单元。创建某个进程就是在一个唯一地址空间创建一个主线程。当某进程开始时,就会执行该进程的主线程。如果只有一个主线程,那么进程和线程实 际上并没有区别。但是,主线程可能会创建其他线程。每个线程又可以创建更多的线程等。某进程的所有线程都在该进程的相同地址空间中执行,但每个线程都是一个独立的执行单元。在线程模型中,如果一个线程被挂起,其他线程可以继续执行。除了共享共同的地址空间之外,线程还共享进程的许多其他资源,如用户id、打开的文件描述符和信号等。打个简单的比方,进程是一个有房屋管理员(主线程)的房子,线程是住在进程房子里的人。房子 里的每个人都可以独立做自己的事情,但是他们会共用一些公用设施,比如同一个信箱、厨房和浴室等。过去,大多数计算机供应商都是在自己的专有操作系统中支持线程。不同系统之间的实现有极大的区别。目前,几乎所有的操作系统都支持Pthread,它是IEEE POSIX 1003.1c的线程标准(POS1X 1995 )。
线程的优点
- 线程创建和切换速度更快
- 线程的响应速度更快
- 线程更适合并行计算
线程的缺点
- 由于地址空间共享,线程需要来自用户的明确同步。
- 许多库函数可能对线程不安全。通常,任何使用全局变量或依赖于静态内存内容的函数,线程都不安全。
- 在单CPU系统上,使用线程解决问题实际上要比使用顺序程序慢
线程操作
线程的执行轨迹与进程类似。线程可在内核模式或用户模式下执行。
线程管理函数
pthread_create(thread, attr, function, arg): create thread
pthread_exit(status) : terminate thread
pthread_cancel(thread) : cancel thread
pthread_attr_init(attr) : initialize thread attributes
pthread_attr_destroy(attr): destroy thread attribute
创建线程
- 使用pthread_create()函数
int pthread_create(pthread_t *thread_id,pthread_attr_t *attr,void *(*func)(void*), void *arg);
线程ID
int pthread_equal(pthread_t t1,pthread_t t2);
如果是不同线程,返回0;否则,返回非0。
线程终止
void pthread_exit(void *status);
0退出值表示正常终止,否则为异常终止。
线程连接
int pthread_join (pthread_t thread, void **status ptr);
线程同步
- 当多个线程试图修改同一共享变量或数据结构时,如果修改结果取决于线程的执行顺序,则称之为竞态条件。在并发程序中,绝不能有竞态条件。
互斥量
在Pthread中,互斥量也被称为“锁”,意为互相排斥。允许执行实体仅在有锁的情况下才能继续执行的同步工具。
- 静态方法:
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER
+动态方法:
使用pthread_mutex_init()函数,可通过attr参数设置互斥属性。
死锁预防
- 简单的死锁预防是对互斥量进行排序,并确保每个线程只在一个方向请求互斥量,这样请求序列中就不会有循环。有多种方法可以解决死锁问题:死锁预防、死锁规避、死锁检测和恢复等。
条件变量
- 条件变量提供线程协作的方法。同样需要初始化,且方法同互斥量相同。
信号量
- 信号量是进程同步的一般机制。(计数)信号量是一种数据结构
屏障
- 线程连接操作允许某线程(通常是主线程)等待其他线程终止,在Pthread中,可以采用的机制是屏障以及一系列屏障函数。
Linux中的线程
- Linux不区分进程和线程。对于Linux内核,线程只是一个与其他进程共享某些资源的进程。