C++ 线程同步 event事件

本文介绍了线程和事件的概念及使用方法,包括线程创建、事件对象的创建与操作,通过实例演示了如何利用事件对象实现三个线程的顺序执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、线程

    线程是指进程内的一个执行单元,也是进程内的可调度实体;当进程启动的同时启动了一个线程,叫做主线程或者执行线程;一个进程可以有多个线程,每个线程都共享进程的地址空间,并且共享进程地址空间内的资源和各种数据;每个线程都占用CPU份额,也就是CPU的时间,线程就是数据在CPU上运行,是个动作。线程可以创建子线程。主线程退出,主线程下的所有子线程都失效,主线程所在进程也被系统撤销,地址空间也被释放。同一时刻,一个CPU不能运行两个线程。

二、事件

事件对象是最基本的内核对象;事件对象包含引用计数、事件类型、事件的通知状态等信息。主要分为两大类:人工重置对象和自动重置对象。人工重置对象可以同时有多个线程等待到时间对象,成为可调度线程;自动重置对象,等待该事件对象的多个线程只能有一个线程成为可调度线程。若为自动重置事件对象,当某一个线程等待到事件对象以后,系统自动将事件变为未通知状态。

三、函数介绍
HANDLE WINAPI CreateEvent(
  __in          LPSECURITY_ATTRIBUTES lpEventAttributes, //事件对象的安全属性,如果为Null不能被子进程继承If this parameter is NULL, the handle cannot be inherited by child processes
  __in          BOOL bManualReset,//事件对象的类型,TRUE表示人工重置事件对象,FLASE表示自动重置事件对象;
  __in          BOOL bInitialState,//事件初始状态 true通知状态;flase 未通知状态
  __in          LPCTSTR lpName//事件对象的名称If lpName is NULL, the event object is created without a name
);

BOOL SetEvent(
  HANDLE hEvent 
); //This function sets the state of the specified event object to signaled.设为有信号状态
BOOL ResetEvent(   HANDLE hEvent ); //This function sets the state of the specified event object to nonsignaled.设为无信号状态

 创建线程

HANDLE WINAPI CreateThread(
  __in          LPSECURITY_ATTRIBUTES lpThreadAttributes,//指向安全属性的指针
  __in          SIZE_T dwStackSize,//初始线程栈的大小
  __in          LPTHREAD_START_ROUTINE lpStartAddress,//指向线程函数的指针
  __in          LPVOID lpParameter,//线程参数
  __in          DWORD dwCreationFlags,//创建标识If this value is zero, the thread runs immediately after creation.
  __out         LPDWORD lpThreadId//指向存放线程ID的指针
);
//Creates a thread to execute within the virtual address space of the calling process. 在调用进程的虚拟地址空间中创建一个线程来执行。

四、笔试题

编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推

// Multithreading.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include <Windows.h>
#include <iostream>
using namespace std;

HANDLE hEventA = INVALID_HANDLE_VALUE;
HANDLE hEventB = INVALID_HANDLE_VALUE;
HANDLE hEventC = INVALID_HANDLE_VALUE;

DWORD __stdcall ThreadA(LPVOID lparam)
{
    DWORD dRet = TRUE;
    int nNums = 0;
    while(1)
    {
        WaitForSingleObject(hEventA,INFINITE);
        ResetEvent(hEventA);
        cout<<"A"<<endl;
        nNums++;
        SetEvent(hEventB);
        //Sleep(10);
        if (nNums == 10)
        {
            break;
        }
    }
    return dRet;
}

DWORD __stdcall ThreadB(LPVOID lparam)
{
    int nNums = 0;
    DWORD dRet = TRUE;
    while(1)
    {
        WaitForSingleObject(hEventB,INFINITE);
        ResetEvent(hEventB);
        //ResetEvent(hEventA);
        cout<<"B"<<endl;
        nNums++;
        SetEvent(hEventC);
        //Sleep(10);
        if (nNums == 10)
        {
            break;
        }
    }
    return dRet;
}

DWORD __stdcall ThreadC(LPVOID lparam)
{
    int nNums = 0;
    DWORD dRet = TRUE;
    while(1)
    {
        WaitForSingleObject(hEventC,INFINITE);
        ResetEvent(hEventC);
        //ResetEvent(hEventB);
        cout<<"C"<<endl;
        nNums++;
        SetEvent(hEventA);
        //Sleep(10);
        if (nNums == 10)
        {
            break;
        }
    }
    return dRet;
}


int _tmain(int argc, _TCHAR* argv[])
{
    int a = sizeof(long);

    hEventA = CreateEvent(NULL, true, true, L"eventa");
    hEventB = CreateEvent(NULL, true, false, L"eventb");
    hEventC = CreateEvent(NULL, true, false, L"eventc");

    HANDLE hThreadA = INVALID_HANDLE_VALUE;
    HANDLE hThreadB = INVALID_HANDLE_VALUE;
    HANDLE hThreadC = INVALID_HANDLE_VALUE;

    hThreadA = CreateThread(NULL, 0, ThreadA, NULL, 0, NULL);
    hThreadB = CreateThread(NULL, 0, ThreadB, NULL, 0, NULL);
    hThreadC = CreateThread(NULL, 0, ThreadC, NULL, 0, NULL);
    
    system("pause");

    if (NULL != hEventA)
    {
        CloseHandle(hEventA);
        hEventA = INVALID_HANDLE_VALUE;
    }
    if (NULL != hEventB)
    {
        CloseHandle(hEventB);
        hEventB = INVALID_HANDLE_VALUE;
    }
    if (NULL != hEventC)
    {
        CloseHandle(hEventC);
        hEventC = INVALID_HANDLE_VALUE;
    }
    if (NULL != hThreadA)
    {
        CloseHandle(hThreadA);
        hThreadA = INVALID_HANDLE_VALUE;
    }
    if (NULL != hThreadB)
    {
        CloseHandle(hThreadB);
        hThreadB = INVALID_HANDLE_VALUE;
    }
    if (NULL != hThreadC)
    {
        CloseHandle(hThreadC);
        hThreadC = INVALID_HANDLE_VALUE;
    }
    return 0;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值