win32 多线程 (五)Event

Event是内核对象,他可以分为自动和手动两种模式。

HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);
参数
lpEventAttributes  安全属性。NULL 表示使用默认属性。该属性在
Windows 95中会被忽略。
bManualReset  如为FALSE,表示这个event  将在变成激发状态
(因而唤醒一个线程)之后,自动重置(reset)为
非激发状态。如果是TRUE,表示不会自动重置,
必须靠程序操作(调用ResetEvent())才能将激发
状态的event  重置为非激发状态。
bInitialState  如为TRUE,表示这个event  一开始处于激发状
态。如为FALSE,则表示这个event  一开始处于
非激发状态。
lpNameEvent  对象的名称。任何线程或进程都可以根据这
个文字名称,使用这一event  对象。
SetEvent()  把event  对象设为激发状态
ResetEvent()  把event  对象设为非激发状态(译注:在此我要提醒读者,
"Reset" 的意思是“设定为非激发状态”,而非“重新设定为
激发状态”。)
PulseEvent()  如果是一个 Manual Reset Event :把event  对象设为激发状
态,唤醒“所有”等待中的线程,然后event  恢复为非激发
状态。如果是一个Auto  Reset  Event:把event  对象设为激
发状态,唤醒“一个”等待中的线程,然后event  恢复为非
激发状态

下面做一个模拟实验,用两个线程轮流输出10次,当然哪个先开始也是可以控制的。

#pragma once
#include <Windows.h>
#include <iostream>

using namespace std;

class EventOption
{
public:
    EventOption(void);
    ~EventOption(void);
    void StartRnner();
    void ReleaseOption();
private:
    static DWORD WINAPI ThreadFunctionA(LPVOID param);
    static DWORD WINAPI ThreadFunctionB(LPVOID param);
    void FunctionA();
    void FunctionB();
private:
    HANDLE m_hThreadA;
    HANDLE m_hThreadB;
    HANDLE m_hEventA;
    HANDLE m_hEventB;
};

#include "EventOption.h"

EventOption::EventOption(void)
{
}

EventOption::~EventOption(void)
{
}
// interface
void EventOption::StartRnner()
{
    m_hEventA = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_hEventB = CreateEvent(NULL, TRUE, FALSE, NULL);
    SetEvent(m_hEventA);
    m_hThreadA = CreateThread(NULL, 0, ThreadFunctionA, this, 0, NULL);
    m_hThreadB = CreateThread(NULL, 0, ThreadFunctionB, this, 0, NULL);
}

void EventOption::ReleaseOption()
{
    WaitForSingleObject(m_hThreadA, INFINITE);
    WaitForSingleObject(m_hThreadB, INFINITE);
    CloseHandle(m_hEventA);
    CloseHandle(m_hEventB);
    CloseHandle(m_hThreadA);
    CloseHandle(m_hThreadB);
}
//private
DWORD EventOption::ThreadFunctionA(LPVOID param)
{
    EventOption *pThis = (EventOption*)param;
    pThis->FunctionA();
    return 0;
}
DWORD EventOption::ThreadFunctionB(LPVOID param)
{
    EventOption *pThis = (EventOption*)param;
    pThis->FunctionB();
    return 0;
}

void EventOption::FunctionA()
{
    int iCount = 10;
    while(iCount--)
    {
        WaitForSingleObject(m_hEventA, INFINITE);
        cout<<"FunctionA: "<<iCount<<endl;
        ResetEvent(m_hEventA);
        SetEvent(m_hEventB);
    }
}

void EventOption::FunctionB()
{
    int iCount = 10;
    while(iCount--)
    {
        WaitForSingleObject(m_hEventB, INFINITE);
        cout<<"FunctionB: "<<iCount<<endl;
        ResetEvent(m_hEventB);
        SetEvent(m_hEventA);
    }
}

#include "EventOption.h"
int _tmain(int argc, _TCHAR* argv[])
{
    EventOption test;
    test.StartRnner();
    test.ReleaseOption();
    ::getchar();
    return 0;
}

win32 多线程 (五)Event

时间: 2024-11-02 15:57:07

win32 多线程 (五)Event的相关文章

由《win32多线程程序设计》临界区的问题所想

之前看侯捷翻译的<win32多线程程序设计>中关于线程同步中的临界区问题,其中举得例子是对链表的操作.死锁的问题是对一个Swaplist函数的问题,现列举代码如下: void SwapLists(List *list, List *list2){ List *tmp_list; EnterCriticalSection(list1->critical_sec); EnterCriticalSection(list2->critical_sec); tmp->list = li

win32多线程(三) 死锁

任何时候当一段代码需要两个(或更多)资源时,都有潜在性的死锁. void SwapLists(List *list1, List *list2) { List *tmp_list; EnterCriticalSection(list1->m_section); EnterCriticalSection(list2->m_section); tmp->list = list1->head; list1->head = list2->head; list2->head

win32多线程 (一) 线程创建与结束等待

#include "stdafx.h"#include <Windows.h>#include <iostream> using namespace std; DWORD WINAPI ThreadFuncFirst(LPVOID param){ int iCount = 50; while(iCount--){  cout<<"\nThreadFuncFirst:"<<iCount; } return 0;} DWO

Win32 多线程的创建方法,区别和联系

Win32多线程的创建方法主要有: CreateThread() _beginthread()&&_beginthreadex() AfxBeginThread() CWinThread类 一.简介 CreateThread: Win32提供的创建线程的最基础的API,用于在主线程上创建一个线程.返回一个HANDLE句柄(内核对象).在内核对象使用完毕后,一般需要关闭,使用CloseHandle()函数. _beginthread()&&_beginthreadex():_

win32多线程 (二)线程同步之临界区 (critical sections)

所谓critical sections 意指一小块“用来处理一份被共享之资源”的程序代码.你可能必须在程序的许多地方处理这一块可共享的资源.所有这些程序代码可以被同一个critical  section 保护起来.为了阻止问题发生,一次只能有一个线程获准进入critical  section 中.critical section 并不是核心对象.使用方法: CRITICAL_SECTION g_section; 1:初始化 InitializeCriticalSection(&g_section

win32多线程设计总结

近期拜读了win32多线程程序设计,总结了这么几点 多线程的主要问题在于线程同步,而线程调用由操作系统实现,因此实现线程同步必须有操作系统提供支持,书中提到过以前我所用过的busy loop与sleep结构来实现线程同步,当时我的感觉就是没有其他办法了,直到遇上了wait系列API,下面就来总结一下各种线程同步方法 1.临界区的使用,优点不需要产生系统内核对象,速度快,效率高.关键API: void InitializeCriticalSection(LPCRITICAL_SECTION lpC

Win32 多线程学习笔记

学到的API函数 一.线程 创建线程.结束线程.获取线程的结束码 CreateThread ExitThread GetExitCodeThread 二.线程结束时触发 创建线程之后,等待线程的结束之后,再继续执行 WaitForSingleObject 创建多个线程之后,等待一组线程(或其中的一个)结束,再继续执行 WaitForMultipleObjects 将消息循环与内核对象的等待合并 MsgWaitForMultipleObjects 三.同步 SendMessage 是同步的 Pos

win32多线程编程

关于多线程多进程的学习,有没有好的书籍我接触的书里头关于多线程多进程部分,一是<操作系统原理>里面讲的相关概念   一个是<linux基础教程>里面讲的很简单的多线程多进程编程,再就是<VC开发>里头讲一点总觉得自己学的不透彻,多线程多进程这部分没啥信心    <win32多线程程序设计>华中科技大学出版社2001-1版本

Win32多线程程序设计

Win32多线程程序设计 "多线程多任务"是程序开发者和用户都需要的一个重要资产.从WindowsNT开始,完全支持32位程序的抢占式多任务.带领我们进入了"多线程多任务"时代. 基本概念 进程(processes) 从win32角度来看,进程含有内存和资源,被进程拥有的内存理论上可达2GB,资源包括内核对象(handle,mutex-),user资源(对话框,字符串-),GDI资源(cdc和brush-). 内存(memory) 每个进程存储数据的地方,分为: C