多核多线程同步

from: http://book.51cto.com/art/201009/224283.htm

1.2.6  多核多线程同步

本书多线程的实现主要是在Windows平台上,因此WinThread和OpenMP是最主要的实现。多线程实现的核心是并行,并行的难点是同步。因为往往会导致程序出错或者效率不高。

那么什么是同步?我们知道多线程的程序设计中需要实现多个线程共享同一段代码,这时,由于线程和线程之间互相竞争CPU资源,会使得线程无序地访问这些共享资源,最终可能导致无法得到正确的结果,这就是竞争。为了保证数据的一致性,避免对共享数据的访问造成数据的不一致性和错误,就需要同步。

同步方法和同步结构有很多,包括但不限于:

互斥量;

原子操作;

临界区;

路障;

事件;

信号量。

互斥是指在同一个时间,同一个地点不能有两件事情同时存在。作为互斥设备,有两个状态:上锁和空闲。同一个时刻只能有一个线程能对互斥量加锁。对于一个已经被加锁的互斥量,另外一个线程试图对它加锁时,该线程会被阻塞,直到该互斥量被释放。在WinThread编程中实现时,主要使用mutex;在OpenMP中,类似的实现如omp_lock_t。

原子操作是指执行指令过程中不可分割的最小单元。比如声明变量的操作、给变量直接赋值的操作,这些都是原子操作,这些操作是安全的。在多线程的程序中,一旦将某         个关键代码封装成一个原子操作,那么对它们的操作就不会存在不同步的情况。因此原            子操作或者不执行,或者不分开的执行,这种操作保证了数据的完备性。在WinThread编程中,原子操作有Interlocked函数,例如InterlockedIncrement、InterlockedDeccrement、InterlockedExchange等; 在OpenMP中,类似的实现如#pragma omp atomic。

临界区是一种多线程必须互斥访问的代码段,保证了原子性。一般都是在用户级线程实现的,开销较小。临界区的大小会影响性能,应尽可能分割成小块,提高并行度。在WinThread编程中,用EnterCriticalSection和LeaveCriticalSection实现,在OpenMP中,用#pragma omp critical来实现。

路障是另外一种同步机制。主要用于逻辑计算的控制流操作。通过这种方法,任何线程在一个控制点等待其他所有线程在这个点完成,然后继续下面的处理。这种方法保证了任何一个线程不会在其他线程还没有到达前往下进行。路障的性能因素要考虑,包括线程数的多少和粒度的大小。过细的粒度,或者负载不均衡的多线程,会导致路障有很差的性能。在OpenMP中,路障大部分是隐式实现的,如#pragma omp parallel for在循环结束时会有线程的同步、#pragma omp single、#pragma omp section也类似,还有专门的语句#pragma omp barrier。

有时线程并不是要访问某个受保护的数据或资源,而是需要等待某一事件(event)的发生,这在GUI编程中十分常见。事件主要在WinThread中实现,事件用于一个线程通知另一线程某一事件的发生(发信号表示某一操作已经完成),它是同步对象中形式最简单的一种,而且其同步的机制也是最具有弹性的。事件存在两种状态:激发状态和未激发状态(Signal/True、Unsignal/False)。事件可分为两类,即手动设置与自动恢复;前者需要程序手动设置,如SetEvent以及ResetEvent;后者指一旦事件发生并处理后,自动恢复到没有事件状态。

信号量(Semaphore)也是WinThread的常见同步结构。它也是一个核心对象,拥有计数器,用来管理大量有限的系统资源。当计数器大于零时,信号量为有信号状态;当计数器为零时,信号量处于无信号状态。当线程用信号量对象的句柄作参数来调用等待函数WaitForSingleObject时,系统会检查该信号量所对应的资源数是否大于0(即资源是否可用),若大于0(称为有信号signaled)则减少资源计数并唤醒线程,若等于0(称为无信号nonsignaled)则让线程进入睡眠状态直到(超出指定时间或当指定时间为无限时)占用该资源的其他线程释放资源并增加资源的计数(使信号量大于0,即有信号或有资源可用)为止。通过创建信号量,等待多个对象以及释放信号量方式实现同步。信号量的本质就是PV操作,对应了两个原子操作。典型应用场景是多线程下保护共享资源的使用。例如有n个共享资源,一开始信号量的值是n,当一个线程需要获取一个资源时,就做一个P操作,当资源使用完毕后做一个V操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值