• c++ 多线程编程


    创建线程

    HANDLE WINAPI CreateThread( 
    	 LPSECURITY_ATTRIBUTES lpThreadAttributes,  //线程内核对象的安全属性,一般传入NULL表示使用默认设置
    	 SIZE_T dwStackSize,     //线程栈空间大小。传入0表示使用默认大小(1MB)
    	 LPTHREAD_START_ROUTINE lpStartAddress,  //新线程所执行的线程函数地址,多个线程可以使用同一个函数地址
    	 LPVOID lpParameter,    //传给线程函数的参数
    	 DWORD dwCreationFlags,  //指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()
    	 LPDWORD lpThreadId);   //将返回线程的ID号,传入NULL表示不需要返回该线程ID号
    
    函数返回值:成功返回新线程的句柄,失败返回NULL
    
    

    线程锁机制

    使用临界区变量控制线程同步

    //  创建5个线程同时向文件写数据,写数据时其他线程等待
    #include "stdafx.h"
    #include <Windows.h>
    
    HANDLE hFile = nullptr;
    CRITICAL_SECTION cs;  //  临界区全局变量
    DWORD WINAPI Thread(LPVOID lpParam);
    
    DWORD WINAPI Thread(LPVOID lpParam)
    {
      int n = (int)lpParam;
      DWORD dwWrite;
      for (size_t i = 0; i < 10; ++i)
      {
        EnterCriticalSection(&cs);
        //  写文件
        char str[512] = {0};
        sprintf(str, "Thread%d print : %d 
    ", n, i);
        WriteFile(hFile, str, strlen(str), &dwWrite, nullptr);
        printf("Thread%d print : %d 
    ", n, i);
        LeaveCriticalSection(&cs);
        Sleep(1000);
      }
    
      return 0;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
      HANDLE hThread[5];
    
      //  创建文件
      char *szName = "a.txt";
      WCHAR name[20] = {0};
      MultiByteToWideChar(CP_ACP, 0, szName, strlen(szName) + 1, name, sizeof(name) / sizeof(name[0]));
      hFile = CreateFile(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
      if (INVALID_HANDLE_VALUE == hFile)
      {
        return 0;
      }
    
      //  初始化临界区
      InitializeCriticalSection(&cs);
    
      //  创建线程,同时写文件
      for (size_t i = 0; i < 5; ++i)
      {
        hThread[i] = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)Thread, (LPVOID)(i + 1), 0, nullptr);
      }
    
      //  等待所有线程结束
      WaitForMultipleObjects(5, hThread, TRUE, INFINITE);
    
      //  删除临界区
      DeleteCriticalSection(&cs);
    
      //  关闭文件句柄
      CloseHandle(hFile);
    
      getchar();
      return 0;
    }
    

    线程通信Event

    多线程通讯,线程1过10秒后激活事件,线程2等待事件激活后执行

    #include "stdafx.h"
    #include <Windows.h>
    
    DWORD WINAPI ThreadProc1(LPVOID lpParam);
    DWORD WINAPI ThreadProc2(LPVOID lpParam);
    HANDLE hEvent = nullptr;
    HANDLE hThread1 = nullptr;
    HANDLE hThread2 = nullptr;
    
    DWORD WINAPI ThreadProc1(LPVOID lpParam)
    {
      for (size_t i = 0; ; ++i)
      {
        if (i == 10)
        {
          //  激活事件,设置为有信号
          SetEvent(hEvent);
        }
        printf("[ThreadProc1] : %d 
    ", i);
        Sleep(1000);
      }
      return 0;
    }
    
    DWORD WINAPI ThreadProc2(LPVOID lpParam)
    {
      //  INFINITE等待hEvent激活
      if (WAIT_OBJECT_0 == WaitForSingleObject(hEvent,INFINITE))
      {
        for (size_t i = 0; ; ++i)
        {
          printf("{ThreadProc2} : %d 
    ", i);
          Sleep(1000);
        }
      }
      return 0;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
      /**
      * HANDLE CreateEvent(
        LPSECURITY_ATTRIBUTES lpEventAttributes,
        BOOL bManualReset, 为TRUE时,需要手动设置为无信号(使用ResetEvent()),为FLASE线程被释放时自动无信号
        BOOL bInitialState,初始化状态,当TRUE,初始状态为有信号状态;当FALSE,初始状态为无信号状态
        LPCSTR lpName
      );
       */
      hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
    
      hThread1 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, nullptr, 0, nullptr);
      hThread2 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, nullptr, 0, nullptr);
    
      getchar();
      return 0;
    }
    
  • 相关阅读:
    idea 的搭建 maven spark开发环境
    自己的简单数据分析流程
    自己对golang中各个文件的理解
    通用android studio gradle 文件(电商商家版,两个gradle不同)
    android与golang的http请求
    Leetcode 98 验证二叉搜索树
    leetcode 830较大分组的位置
    Leetcode 种花问题
    leetcode 86 分割链表
    Leetcode 509 斐波那契数
  • 原文地址:https://www.cnblogs.com/xiongyungang/p/11904216.html
Copyright © 2020-2023  润新知