• C++多线程3


    #include "stdafx.h"
    #include <windows.h>
    #include <process.h>  
    
    int g_count;
    const int ThreadNum = 10;
    unsigned int __stdcall Func(LPVOID pm)
    {
        int id = *(int*)pm;
        Sleep(10);
        g_count++;
        printf_s("id=%d,count=%d 
    ", id, g_count);
        return 0;
    }
    
    int main()
    {
        HANDLE  handle[ThreadNum];
        g_count = 0;
        for (int i = 0; i < ThreadNum; ++i)
        {
            handle[i] = (HANDLE)_beginthreadex(NULL, 0, Func, (LPVOID)&i, 0, NULL);
        }
        WaitForMultipleObjects(ThreadNum, handle, TRUE, INFINITE);
        system("pause");
        return 0;
    }

    要求:

    子线程输出的线程序号不能重复。(主线程和子线程需要同步)

    全局变量g_count的输出必须递增。(子线程之间需要互斥)

    1,用临界区CRITICAL_SECTION来解决子线程之间的互斥

    CRITICAL_SECTION g_section;//声明一个临界区资源
    InitializeCriticalSection(&g_section);//初始化
    EnterCriticalSection(&g_section);//开始进入临界区代码段
    LeaveCriticalSection(&g_section);//离开临界区代码段
    DeleteCriticalSection(&g_section);//销毁
    #include "stdafx.h"
    #include <windows.h>
    #include <process.h>  
    
    int g_count;
    const int ThreadNum = 10;
    CRITICAL_SECTION g_section;
    unsigned int __stdcall Func(LPVOID pm)
    {
        int id = *(int*)pm;
        Sleep(10);
        EnterCriticalSection(&g_section);//进入临界区后各个线程之间互斥
        g_count++;
        //InterlockedIncrement((LPLONG)&g_count);
        printf_s("id=%d,count=%d 
    ", id, g_count);
        LeaveCriticalSection(&g_section);
        return 0;
    }
    
    int main()
    {
        InitializeCriticalSection(&g_section);
        HANDLE  handle[ThreadNum];
        g_count = 0;
        for (int i = 0; i < ThreadNum; ++i)
        {
            handle[i] = (HANDLE)_beginthreadex(NULL, 0, Func, (LPVOID)&i, 0, NULL);
        }
        WaitForMultipleObjects(ThreadNum, handle, TRUE, INFINITE);
        DeleteCriticalSection(&g_section);
        system("pause");
        return 0;
    }

    2用事件解决主线程和子线程的同步问题

    //CreateEvent创建一个事件

    HANDLE CreateEvent(

     LPSECURITY_ATTRIBUTES lpEventAttributes,//安全参数,一般为NULL

     BOOL bManualReset, //TRUE手动(SetEvent后需要ResetEvent) , FALSE自动,对事件对象调用WaitForSingleObject后自动是对象变成未触发的状态

     BOOL bInitialState, //TRUE 初始状态就是触发状态

     LPCTSTR lpName //事件对象的名字,传入NULL表示匿名的事件对象

    );

    //SetEvent 触发一个事件内核对象,必有一个或者多个等待状态的线程变成可调度的状态

    BOOL SetEvent(HANDLE hEvent);

    //ResetEvent 事件变成未触发状态

    BOOL ResetEvent (HANDLE hEvent);

    最后的代码如下

    #include "stdafx.h"
    #include <windows.h>
    #include <process.h>  
    
    int g_count;
    const int ThreadNum = 10;
    CRITICAL_SECTION g_section;
    HANDLE g_handle;
    
    unsigned int __stdcall Func(LPVOID pm)
    {
        int id = *(int*)pm;
        SetEvent(g_handle);//事件被触发后,线程变成可调度状态
        Sleep(10);
        EnterCriticalSection(&g_section);//进入临界区
        g_count++;
        printf_s("id=%d,count=%d 
    ", id, g_count);//离开临界区
        LeaveCriticalSection(&g_section);
        return 0;
    }
    
    int main()
    {
        g_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
        InitializeCriticalSection(&g_section);
    
        HANDLE  handle[ThreadNum];
        g_count = 0;
        for (int i = 0; i < ThreadNum; ++i)
        {
            handle[i] = (HANDLE)_beginthreadex(NULL, 0, Func, &i, 0, NULL);
            WaitForSingleObject(g_handle, INFINITE);//等待事件被触发
        }
        WaitForMultipleObjects(ThreadNum, handle, TRUE, INFINITE);//等待所有的子线程被触发
        CloseHandle(g_handle);
        DeleteCriticalSection(&g_section);
        system("pause");
        return 0;
    }

    输出

    id没有相同的,说明主线程和子线程之间已经同步,

    count递增,说明子线程之间已经互斥

  • 相关阅读:
    JavaWeb
    Network
    JavaWeb
    Maven
    IDEA
    Maven
    Network
    JavaWeb
    JavaWeb
    JavaWeb
  • 原文地址:https://www.cnblogs.com/July7th/p/6241682.html
Copyright © 2020-2023  润新知