C++ thread synchronization event event

1. Thread

    A thread refers to an execution unit in a process, and it is also a schedulable entity in a process; when a process starts, a thread is started at the same time, called the main thread or execution thread; a process can have multiple threads, and each thread shares the process address space, and share the resources and various data in the process address space; each thread occupies the CPU share, that is, the time of the CPU, and the thread is the data running on the CPU, which is an action. Threads can create child threads. When the main thread exits, all sub-threads under the main thread are invalid, the process where the main thread is located is also cancelled by the system, and the address space is also released. At the same time, one CPU cannot run two threads.

2. Events

The event object is the most basic kernel object; the event object contains information such as reference count, event type, and event notification status. There are two main categories: manual reset objects and automatic reset objects. When manually resetting an object, multiple threads can wait for the time object at the same time and become a schedulable thread; when an object is automatically reset, only one thread of multiple threads waiting for the event object can become a schedulable thread. If the event object is automatically reset, when a thread waits for the event object, the system automatically changes the event to an unnotified state.

3. Function introduction

HANDLE WINAPI CreateEvent(
  __in LPSECURITY_ATTRIBUTES lpEventAttributes, //Security attributes of the event object, if this parameter is NULL, the handle cannot be inherited by child processes
  __in BOOL bManualReset,//The type of event object, TRUE means manually reset the event object, FLASE means automatically reset the event object;
  __in BOOL bInitialState,//Event initial state true notification state; flase not notified state
  __in LPCTSTR lpName//The name of the event object 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. Set to signaled state
BOOL ResetEvent( HANDLE hEvent ); //This function sets the state of the specified event object to nonsignaled. Set to no signal state

 create thread

HANDLE WINAPI CreateThread(
  __in LPSECURITY_ATTRIBUTES lpThreadAttributes,//pointer to security attributes
  __in SIZE_T dwStackSize,//The size of the initial thread stack
  __in LPTHREAD_START_ROUTINE lpStartAddress,//pointer to thread function
  __in LPVOID lpParameter,//Thread parameter
  __in          DWORD dwCreationFlags,//创建标识If this value is zero, the thread runs immediately after creation.
  __out LPDWORD lpThreadId//Pointer to store thread ID
);
//Creates a thread to execute within the virtual address space of the calling process.

4. Written test questions

Write a program to open 3 threads. The IDs of these 3 threads are A, B, and C. Each thread prints its own ID on the screen 10 times, and the output results must be displayed in the order of ABC; for example: ABCABC .... in turn recursively

// Multithreading.cpp : Defines the entry point for the console application.
//

#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;
}



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325772972&siteId=291194637