zoukankan      html  css  js  c++  java
  • 一些多线程编程的例子(转)

    转自 http://www.cppblog.com/gohan/archive/2007/02/16/18822.html

     

    Someone recently asked me what I recommend for synchronizing worker threads and I suggested setting an event. This person's response was that you could not do that since worker threads do not support a message pump (UI threads are required to support messages). The confusion here is that events and messages are different animals under windows.

    我忘记了我从哪里copy的这些例子代码,他们可是非常简单而有趣的。如果有人知道这些代码的作者,我一定要好好感谢你和这位作者。

    注意这里有很多对于没有提及的MFC的支持。像_beginthreadex(一个C运行时库调用)的API可以在MFC应用程序中替换成AfxBeginThread。(建议在mfc情况下也用_beginthreadex

     

     

    无同步(No Synchronization

     

    这第一个例子描述了两个互不同步的线程。进程中的首要线程--主函数循环,输出全局整形数组的内容。还有一个线程“Thread”不停的给数组每个元素+1


    The thread called "Thread" continuously populates the global array of integers.

     

    Code

     

     

    注意这个例子的输出,红色的数处在一个主线程抢先于Thread工作过程中执行的打印动作

    81751652 81751652 81751651 81751651 81751651
    81751652 81751652 81751651 81751651 81751651
    83348630 83348630 83348630 83348629 83348629
    83348630 83348630 83348630 83348629 83348629
    83348630 83348630 83348630 83348629 83348629

     

     

    关键区域/临界区域 对象(Critical Section Objects

     

    如果你想让主线程等待Thread线程处理好全局数组再做打印,一种解决方法是使用关键区域对象。


    关键区域对象提供同步于使用互斥器(Mutex)对象很相似, 除了关键区域对象只能在一个进程内发挥效用。Event, mutex, 以及 semaphore 对象也可以用在单进程的应用程序中, 但是关键区域对象提供一个相对快捷更加高效的同步机制. 就像互斥器一样, 一个关键区域对象只能同时被一个线程拥有, 这个关键区域能够在同时发生的数据存取时保护共享资源. 获取关键区域的先后顺序不定,可是不用太担心,系统对于每一个线程都是平等的。

     

    Code

     

    互斥器(Mutex Objects

     

    一个互斥器是一个信号状态的同步对象,当它不属于任何一个线程时就用信号来体现,当被拥有时他的信号状态就为None. 同一时刻只有一个线程可以拥有互斥器, 互斥器这个名字来自于他们对于并列的线程存取共享资源时表现出的行为。举个例子,避免两个线程同时写入一个共享内存,每一个线程当需要执行存取共享资源的代码时首先等待直到自己获得拥有权. 在存取共享资源之后,线程释放对互斥器的拥有权。

     

    两个或以上的进程可以调用CreateMutex 来建立同样名字的互斥器. 实际上第一个进程建立的这个互斥器, 随后的进程只是得到了那个存在的互斥器的句柄. 这能使多进程共用一个互斥器, 当然用户应该有确保建立互斥器的进程首先启动的责任. 使用这种技术,你应该将这个 bInitialOwner标记设置成FALSE; 否则, 它可以因不同的进程最初拥有它而带来困难.

    多进程可以有同一个mutex对象的句柄, mutex对象能够用于多进程间同步.

     

    下面的对象共享机制是适用的:

    ·         一个子进程通过CreateProcess 函数被建立,当CreateMutexlpMutexAttributes 参数给予相应的mutex对象指针它可以继承到一个mutex对象的句柄.

    ·         一个进程可以在DuplicateHandle 函数中指定一个mutex对象句柄来建立一个句柄的拷贝由其他进程使用.

    ·         一个继承可以指定一个mutex的名字通过 CreateMutex 函数得到这个mutex对象的句柄.

     

     

    总的来说, 如果你想要进行线程同步,临界区域更高效些。

     

     

    Code

     

     

     

     

    Event Objects事件对象

     

    若我们想要强制第二线程在主线程完成全局数组的内容输出时执行该如何?这样的话每行的输出就只是递增1

    一个事件对象也是一个可以通过SetEvent(常用) or PulseEvent 函数设置像信号般的状态的同步对象. 下面是两种类型的事件对象.

     

    Object

    Description

    Manual-reset event
    手动激发对象

    只有使用ResetEvent 函数才可以将其设置为无激发状态. 当它在激发状态时, 它会激发所有正在等待的线程, 执行对相同 event对象的线程会立即从wait函数返回.

    Auto-reset event
    自动激发对象

    一个只相应一个线程的wait函数的事件对象(当这个对象是激发状态),wait函数返回同时事件对象自动变成无激发状态 ,当没有线程执行wait事件对象仍然是激发状态.

    event object的用处就在于它可以在它发生时向等待着的线程发出信号标志从而使其wait结束举个例子, overlapped I/O 操作时, 当异步操作完成时系统设置了那个由程序员指定(specified)的事件对象为信号状态. A 一个单一线程可以指定许多不同的事件对象在许多同时发生的overlapped 操作运作, 调用一个多对象的wait函数可以当任意一个event object激发时结束等待.

    在一个线程中可使用 CreateEvent 函数建立一个event object. 在这个线程中指定这个event object 的特性是manual-reset 或者 auto-reset . 在这个线程中也可以命名一个event object. 其他进程中的线程也可以使用 OpenEvent 通过event object的名字打开一个现存event object . 另外关于mutex, event, semaphore, 以及 timer objects的其他信息, 就参考《Interprocess Synchronization》的文章.

     

    一个线程能够用 PulseEvent 函数设置一个event object 为信号状态而后激发当前适当数量的wait线程,之后切换为无信号状态对于一个manual-reset event object, 所有的等待线程被返回(release. 对于一个auto-reset event object, 这个函数只能释放一个等待的线程, 即使有更多线程在等待. 如果没有线程在函数调用时等待, PulseEvent 只是简单的将事件状态设为无信号并且返回(个人注释,这应该是跟setevent最不相同的地方!).

     

     

    Code

     

    Summary of Synchronization Objects

    The MSDN News for July/August 1998 has a front page article on Synchronization Objects. The following table is from that article:

    Name

    Relative speed

    Cross process

    Resource counting

    Supported platforms

    Critical Section

    Fast

    No

    No (exclusive access)

    9x/NT/CE

    Mutex

    Slow

    Yes

    No (exclusive access)

    9x/NT/CE

    Semaphore

    Slow

    Yes

    Automatic

    9x/NT

    Event

    Slow

    Yes

    Yes

    9x/NT/CE

    Metered Section

    Fast

    Yes

    Automatic

    9x/NT/CE

     

  • 相关阅读:
    有道
    excel 数据入库
    iso-8859-1 Unicode 编码
    爬虫编码问题
    WIKi 百科爬虫
    降低耦合性获取微博数据
    Python基础总结3-字符串
    Python基础总结2
    Linux常用命令04(其他命令)
    Linux常用命令03(系统信息)
  • 原文地址:https://www.cnblogs.com/aicro/p/1502538.html
Copyright © 2011-2022 走看看