(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. Java 之文件目录操作

    1.判断文件是否存在 File file = new File("d:\\study\\temp\\test.java"); boolean bl = file.exists(); ...

  2. 网页、JavaScript 数据类型

    JavaScript 数据类型 一.基本数据类型: 字符串.数字.布尔.日期和时间 JavaScript 拥有动态类型 JavaScript 拥有动态类型.这意味着相同的变量可用作不同的类型: 1 v ...

  3. Windows 右键快速运行命令行

    原文见:右键命令行 - yacper - 博客园 方法一:配置文件夹选项 1 打开人任意文件夹,[工具] --> [文件夹选项] --> [文件类型] --> [(无)资料夹] -- ...

  4. Oracle 如何让别人能够连接到你的数据库

    Oracle 初步 --Oracle的一些关键字 i和g只是版本的代号,指oracle运用的技术i代表Internet就是互联网技术g代表grid就是网格技术现在出的最新版是c就是cloud也就是云技 ...

  5. ubuntu 快捷键和安装知识知识

    本文节选自“The Official Ubuntu Book, 7th Edition.pdf” 快捷键部分直接引用原书中图片. Linux Folders Learning Unity Keyboa ...

  6. bug经验

    1.异常信息丢失导致定位问题困难. 2.findbugs工具 3.在某些if语句判断中return,可能会导致文件句柄无法关闭. 4.lastmodified()在win下和linux下的处理是不同的 ...

  7. Swift数据类型之整型和浮点型-备

    Swift提供8.16.32.64位形式的有符号及无符号整数.这些整数类型遵循C语言的命名规约,我归纳了Swift中的整型: 整型示例: print("UInt8 range: \(UInt ...

  8. layout_gravity与gravity的区别

    1:android:gravity 这个是针对控件里的元素来说的,用来控制元素在该控件里的显示位置. 2:android:layout_gravity 这个是针对控件本身而言,用来控制该控件在包含该控 ...

  9. Codeforces 525E Anya and Cubes

    http://codeforces.com/contest/525/problem/E 题意: 有n个方块,上面写着一些自然数,还有k个感叹号可用.k<=n 你可以选任意个方块,然后选一些贴上感 ...

  10. Visual Studio 启动加速

    Who is locking my SQL database?|Deploy a database project with TFS Build Visual Studio 2012 running ...