笔记:线程同步

来源:互联网 发布:飞鸟淘宝客是真的吗 编辑:程序博客网 时间:2024/06/04 19:13

Windows支持4种类型的同步对象,可以用来同步由并发运行的线程所执行的操作:

临界区——CCriticalSection

互斥量——CMutex

事件——CEvent

信号——CSemaphore

这些类封装在MFC中。


临界区:

最简单类型的线程同步对象。用来串行化对由两个或者多个线程共享的链表、简单变量、结构和其他资源的访问。这些线程必须属于相同的进程,因为临界区不能跨越进程的边界工作。

工作思想:每个独占性的访问一个资源的线程可以在访问那个资源之前锁定临界区,访问完毕解锁。若中途有其他线程试图锁定当前线程锁定的临界区,就会阻塞,直到该临界区空闲。阻塞线程不会消耗处理器事件。

CCriticalSection::Lock锁定临界区,CCriticalSection::Unlock解除对临界区的锁定。

eg:两个使用链表的独立线程,一个写入链表,一个读取链表。

//Global dataCCriticalSection g_cs;....//Thread Ag_cs.Lock();//Write to the linked listg_cs.Unlock();....//Thread Bg_cs.Lock();//Read  from the linked listg_cs.Unlock();
PS:CCriticalSection::Lock的另一种形式接受超时值,如果给Lock传递一个超时值,在临界区空闲之前该超时时间段到期,Lock将返回。这种说法是错误的,Lock在解除锁定前不会返回。

Win32 API中包含一组::Interlocked函数执行32位值的操作,可不需显式使用同步对象。


互斥量:

和临界区不同,可以用来同步在相同进程或者不同进程上运行的线程对于进程内线程同步的需要,临界区一般要优于互斥量,因为临界区更快。

eg:假定两个应用程序使用一块共享内存交换数据,内存内部是一个必须防止并发线程访问的链表

//Global dataCMutex g_mutex( FALSE,_T("MyMutex"));....g_mutex.Lock();//Read or write the linked list.g_mutex.Unlock();
传递给CMutex构造函数的第一个参数指定互斥量的初始状态是锁定(TRUE)或者未锁定(FALSE)。第二个参数是指定互斥量名称。

默认情况下,Lock将永远等待知道互斥量变为未锁定,也可以指定一个以毫秒为单位的最大等待时间来建立一个安全失败机制。g_mutex.Lock(60000);

Lock返回非0时表示互斥量空闲,0表示超时时间段首先到期。

PS:如果一个线程锁定了临界区而终止时没有解除临界区的锁定,等待临界区空闲的其他线程将无限期阻塞下去;如果锁定互斥量的线程不能在其终止前解除互斥量的锁定,系统将认为互斥量被“放弃”了自动释放该互斥量,等待进程可以继续执行。





原创粉丝点击