(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源)

翻译文章来源:  msdn - Multithreading: How to Use the Synchronization Classes

注1: 借助了google翻译和金山词霸

注2: 翻译的不当之处,还请多多指正

在多线程间同步资源是在写多线程时常常遇到的问题。有二个以上的线程来訪问同一数据时。常常会导致不可预知的问题。

比如,在同一时间,一个线程在写该数据。而还有一个线程在读该数据,这将不知道读线程到底读出的是什么数据。是老的数据,还是新写入的数据。也或是读出的一部分是老数据、还有一部分是新数据。

MFC提供了一些同步和同步控制类来帮助解决这样的问题。这篇主题一是阐述这些类,二是阐述怎样来使用这些类创建线程安全的典型多线程程序。

Synchronizing resource access between threads is a common problem when writing multithreaded applications. Having two or more threads simultaneously access the same data can lead to undesirable and unpredictable results.
For example, one thread could be updating the contents of a structure while another thread is reading the contents of the same structure. It is unknown what data the reading thread will receive: the old data, the newly written data, or possibly a mixture of
both. MFC provides a number of synchronization and synchronization access classes to aid in solving this problem. This topic explains the classes available and how to use them to create thread-safe classes in a typical multithreaded application.

一个典型的多线程程序会有一个类来声明资源供多个线程间共享使用。

在合理的设计下。线程安全的类不须要调用同步函数。全部的处事都是类的内部,你仅仅须要关注怎样使用这个类,而不须要考虑失效的情况。一个创建线程安全类的有效方法是,把同步类整合到资源类中。

合并同步类到共享类中是一个较直接的方法。

A typical multithreaded application has a class that represents a resource to be shared among threads. A properly designed, fully thread-safe class does not require you to call any synchronization functions. Everything
is handled internally to the class, allowing you to concentrate on how to best use the class, not about how it might get corrupted. An effective technique for creating a fully thread-safe class is to merge the synchronization class into the resource class.
Merging the synchronization classes into the shared class is a straightforward process.

当中一个样例,一个程序维护一系列的账户。这个程序同意三个账户在不同的窗体中被检查。可是仅同意在特定的时间进行改动。当账户改动时。改动后的数据通过网络进行数据存档。

As an example, take an application that maintains a linked list of accounts. This application allows up to three accounts to be examined in separate windows, but only one can be updated at any particular time. When
an account is updated, the updated data is sent over the network to a data archive.

这个样例须要用到全部的三种同步类,由于它同意三个账户同一时候被检查。须要使用CSemaphore来进行限制不超过三个可查的;当试图同一时候查看第四个账户时,程序须要等待其他三个查看账户关闭也或是本次查看失败。当一个账户被改动时,程序使用CCriticalSection来确保在同一时间仅有一个账户被改动,但改动成功后,触发信号CEvent来释放发送信息的线程,这个线程发送新的数据到归档中心。

This example application uses all three types of synchronization classes. Because it allows up to three accounts to be examined at one time, it uses CSemaphore to limit access to three view objects. When an attempt
to view a fourth account occurs, the application either waits until one of the first three windows closes or it fails. When an account is updated, the application uses CCriticalSection to ensure that only one account is updated at a time. After the update
succeeds, it signals CEvent, which releases a thread waiting for the event to be signaled. This thread sends the new data to the data archive.

设计一个线程安全的类: 怎样让一个类做到线程安全,首先加入适当的同步类作为成员变量,放到共享类中。

在上个账户管理的样例中,须要加入一个CSemaphore类的成员变量到视图类中,须要加入一个CCriticalSection成员变量到账户链接列表类中。须要加入一个CEvent成员变量到数据存储类中。

Designing a Thread-Safe Class

To make a class fully thread-safe, first add the appropriate synchronization class to the shared classes as a data member. In the previous account-management example, a CSemaphore data member would be added to the
view class, a CCriticalSection data member would be added to the linked-list class, and a CEvent data member would be added to the data storage class.

下一步,为全部类中的数据改动或訪问资源,加入同步调用;在每一个函数中,须要创建CSingleLock或CMultiLock对像而且调用对像的lock方法;当lock的对像出了作用域之后会被销毁。对像的析构函数会完毕这个操作,当然,也能够手动调用unlock。

Next, add synchronization calls to all member functions that modify the data in the class or access a controlled resource. In each function, you should create either a CSingleLock or CMultiLock object and call that
object's Lock function. When the lock object goes out of scope and is destroyed, the object's destructor calls Unlock for you, releasing the resource. Of course, you can call Unlock directly if you want.

以这样的方式设计出的线程安全类。同意在多线程中轻松的使用,如同使用一个非多线程的类一样,可是却具备较高的安全性。在资源类中封装同步对像和同步訪问提供了线程安全的全部优势,而且没有维护同步代码的缺点。

Designing your thread-safe class in this fashion allows it to be used in a multithreaded application as easily as a non-thread-safe class, but with a higher level of safety. Encapsulating the synchronization object
and synchronization access object into the resource's class provides all the benefits of fully thread-safe programming without the drawback of maintaining synchronization code.

以下的演示样例代码展示了使用成员变量的方法,在共享资源中类中定义了变量m_CritSection(CCriticalSection类型)和一个CSingleLock对像;共享资源(从CWinThread派生)同步时尝试使用m_CritSection对像的地址创建一个CSingleLock实体。尝试锁定资源,获取到资源之后。在共享对像上完毕操作;操作完毕后,使用unlock释放资源的锁定。

The following code example demonstrates this method by using a data member, m_CritSection (of type CCriticalSection), declared in the shared resource class and a CSingleLock object. The synchronization of the shared
resource (derived from CWinThread) is attempted by creating a CSingleLock object using the address of the m_CritSection object. An attempt is made to lock the resource and, when obtained, work is done on the shared object. When the work is finished, the resource
is unlocked with a call to Unlock.

Copy Code

CSingleLock singleLock(&m_CritSection);

singleLock.Lock();

// resource locked

//.usage of shared resource...

singleLock.Unlock();

注意:

CCriticalSection不像其他MFC的同步类,没有超时时间的选项,等待资源被释放的时间将会是无限长的。

Note

CCriticalSection, unlike other MFC synchronization classes, does not have the option of a timed lock request. The waiting period for a thread to become free is infinite.

这样的方法的缺点是: 比相同功能却没有加入同步实体的类略微慢一些;同一时候,假设存在超过一个线程会删除对像,这样的合并的方法可能会工作异常,在这样的情况下。最好是分开维护同步对像。

The drawbacks to this approach are that the class will be slightly slower than the same class without the synchronization objects added. Also, if there is a chance that more than one thread might delete the object,
the merged approach might not always work. In this situation, it is better to maintain separate synchronization objects.

查找关于怎样在不同的情况使用哪种同步类,參考: Multithreading: When to Use the Synchronization Classes

查找很多其它关于同步的信息。參见平台SDK中的描写叙述,查找关于MFC中对多线程的很多其它支持。參见Multithreading with C++ and MFC。

For information about determining which synchronization class to use in different situations, see Multithreading: When to Use the Synchronization Classes. For more information about synchronization, see Synchronization in the
Platform SDK. For more information about multithreading support in MFC, see Multithreading with C++ and MFC.

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源)

Multithreading: How to Use the Synchronization Classes的更多相关文章

  1. Java多线程系列--“JUC锁”07之 LockSupport

    概述 本章介绍JUC(java.util.concurrent)包中的LockSupport.内容包括:LockSupport介绍LockSupport函数列表LockSupport参考代码(基于JD ...

  2. 【JDK1.8】JUC——LockSupport

    一.前言 Basic thread blocking primitives for creating locks and other synchronization classes. 用于创建锁定和其 ...

  3. Java中关于LockSupport的简单入门记录

    LockSupport的JDK的文档描述:Basic thread blocking primitives for creating locks and other synchronization c ...

  4. day9--多线程与多进程

        线程:     什么是线程? 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线 ...

  5. 阻塞和唤醒线程——LockSupport功能简介及原理浅析

    目录 1.LockSupport功能简介 1.1 使用wait,notify阻塞唤醒线程 1.2 使用LockSupport阻塞唤醒线程 2. LockSupport的其他特色 2.1 可以先唤醒线程 ...

  6. JUC 包下工具类,它的名字叫 LockSupport !你造么?

    前言 LockSupport 是 JUC 中常用的一个工具类,主要作用是挂起和唤醒线程.在阅读 JUC 源码中经常看到,所以很有必要了解一下. 公众号:liuzhihangs ,记录工作学习中的技术. ...

  7. Java 并发编程(一) → LockSupport 详解

    开心一刻 今天突然收到花呗推送的消息,说下个月 9 号需要还款多少钱 我就纳了闷了,我很长时间没用花呗了,怎么会欠花呗钱? 后面我一想,儿子这几天玩了我手机,是不是他偷摸用了我的花呗 于是我找到儿子问 ...

  8. LockSupport中的park()与unpark()

    类注释原文:Basic thread blocking primitives for creating locks and other synchronization classes.意思就是Lock ...

  9. Uniform synchronization between multiple kernels running on single computer systems

    The present invention allocates resources in a multi-operating system computing system, thereby avoi ...

随机推荐

  1. Nuget找不到服务器

    Nuget的新地址 http://nuget-prod-v2gallery.trafficmanager.net/api/v2/

  2. c++Socket 异步通讯

    在网络通讯中,由于网络拥挤或一次发送的数据量过大等原因,经常会发生交换的数据在短时间内不能传送完,收发数据的函数因此不能返回,这种现象叫做阻塞. Winsock对有可能阻塞的函数提供了两种处理方式:阻 ...

  3. 内核与ramdisk到底是什么关系

    转自:http://www.lupaworld.com/forum.php?mod=viewthread&tid=61425 原名:内核与ramdisk到底是什么关系? 个人Notes:    ...

  4. JavaScript的68个技巧一

    1. 严格模式 在自己的项目中 你可以坚持只使用" 严格模式 " 或只使用" 非严格模式 "的策略.但如果你要编写健壮的代码应对各种各样的代码连接 你有两个可选 ...

  5. 自定义控件 进度条 ProgressBar-2

    使用 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:bqt ...

  6. jQuery animate easing使用方法

    从jQuery API 文档中可以知道,jQuery自定义动画的函数.animate( properties [, duration] [, easing] [, complete] )有四个参数: ...

  7. MVC 5.0 之奇葩错误-<类型“ASP._Page__ViewStart_cshtml”不从“System.Web.WebPages.StartPage”继承>

    在实际项目中,我们通常添加MVC项目会先添加一个MVC Empty 的项目,然后需要什么在往里面添加. 但是Empty项目里面只有一个路由注册,而且没有_ViewStart.cshtml文件需要自己添 ...

  8. (转)asp.net实现忘记密码找回的代码

    1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or ...

  9. ECMAscript v.s. Javascript

    ECMAscript是一种中性的语言,中性表示与所处环境(宿主环境)无关(客户端/服务器/浏览器),它仅仅是一个纯粹意义上的语言. ECMAscript-262定义了这门语言的基础,或者说规则(比如说 ...

  10. Qt5.4静态编译方法

    静态编译,就是编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(.so或.lib)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖于动态链接库.这样就可以发布单 ...