zoukankan      html  css  js  c++  java
  • Multithreading: How to Use the Synchronization Classes

    (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 转载请标明来源)

  • 相关阅读:
    常用FPGA功能块记录
    鸿蒙相关
    微波相关
    Python库大全
    C#环境实现代码的自动生成编译
    STM32相关
    硬件相关
    C# 获取枚举中文注释
    C# 获取自定义特性值
    Asp.Net Core 中 Host 与 WebHost的区别
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5320524.html
Copyright © 2011-2022 走看看