zoukankan      html  css  js  c++  java
  • 临界区 事件 互斥对象等多线程编程基础

    1、临界区

    #include <windows.h>
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    
    /*
      临界区对象
      用户使用某个线程访问共享资源时,必须是代码段独享该资源,不允许其他线程访问该资源
    */
    
    
    DWORD WINAPI myfunc1(
        LPVOID lpParameter
    );
    DWORD WINAPI myfunc2(
        LPVOID lpParameter
    );
    
    CRITICAL_SECTION Section;//临界区对象
    static int a1 = 0;//全局变量
    
    int main(){
        HANDLE h1,h2;
    
        InitializeCriticalSection(&Section);
        ::Sleep(10000);
    
        h1 = CreateThread(NULL,0,myfunc1,NULL,0,NULL);
        cout<<"线程1开始运行!"<<endl;
        h2 = CreateThread(NULL,0,myfunc2,NULL,0,NULL);
        cout<<"线程2开始运行!"<<endl;
    
        //释放临界区资源对象
        ::CloseHandle(h1);
        ::CloseHandle(h2);
    
        if (getchar()=='q'){
            DeleteCriticalSection(&Section);
            return 0;
        }else
        {
            ::Sleep(100);
            }
    }
    /*
    DWORD WINAPI myfunc1( LPVOID lpParameter ){
        cout<<"线程1正在运行!"<<endl;
        return 0;
    }
    DWORD WINAPI myfunc2(LPVOID lpParameter){
        cout<<"线程2正在运行!"<<endl;
        return 0;
    }
    */
    
    DWORD WINAPI myfunc1( LPVOID lpParameter ){
        while(1){
            EnterCriticalSection(&Section);
            a1++;
            if (a1 < 10000)
            {
                ::Sleep(1000);
                cout<<"Thread 1 was counting "<<a1<<endl;
                LeaveCriticalSection(&Section);
            }else{
                LeaveCriticalSection(&Section);
                break;
            }
        }
        return 0;
    }
    
    DWORD WINAPI myfunc2( LPVOID lpParameter ){
        while(1){
            EnterCriticalSection(&Section);
            a1++;
            if (a1 < 10000)
            {
                ::Sleep(1000);
                cout<<"Thread 2 was counting "<<a1<<endl;
                LeaveCriticalSection(&Section);
            }else{
                LeaveCriticalSection(&Section);
                break;
            }
        }
        return 0;
    }

    2、事件对象

    #include <Windows.h>
    #include <stdio.h>
    #include <iostream>
    
    using namespace std;
    
    DWORD WINAPI myfunc1(LPVOID lpParam);
    DWORD WINAPI myfunc2(LPVOID lpParam);
    
    /*
      事件对象
      用户再程序中使用内核对象的有无信号状态实现线程的同步
    
    **/
    HANDLE hEvent;
    int a = 0;
    
    int main()
    {
        HANDLE h1,h2;
        hEvent = ::CreateEvent(NULL,FALSE,FALSE,NULL);
        ::SetEvent(hEvent);
    
        h1 = ::CreateThread(NULL,0,myfunc1,NULL,0,NULL);
        cout<<"线程1开始运行!"<<endl;
        h2 = ::CreateThread(NULL,0,myfunc2,NULL,0,NULL);
        cout<<"线程2开始运行!"<<endl;
        ::CloseHandle(h1);
        ::CloseHandle(h2);
        
        ::Sleep(10000);
        //cin.get();
        return 0;
    }
    
    DWORD WINAPI myfunc1(LPVOID lpParam)
    {
        while (TRUE)
        {
            ::WaitForSingleObject(hEvent,INFINITE);//请求事件对象
            ::ResetEvent(hEvent);//设置事件对象为无信号状态
            if(a < 10000)
            {
                 a += 1;
                 ::Sleep(1000);
                 cout<<"线程1:"<<a<<endl;
                 ::SetEvent(hEvent);
            }else
            {
                ::SetEvent(hEvent);
                break;
            }
        }
        return 0;
    }
    DWORD WINAPI myfunc2(LPVOID lpParam)
    {
        while (true)
        {
            ::WaitForSingleObject(hEvent,INFINITE);
            ::ResetEvent(hEvent);
            if(a < 10000)
            {
                a += 1;
                ::Sleep(1000);
                cout<<"线程2:"<<a<<endl;
                ::SetEvent(hEvent);
            }else
            {
                ::SetEvent(hEvent);
                break;
            }
        }
        return 0;
    }

    3、互斥对象

    #include <Windows.h>
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    
    /*
      互斥对象
      互斥对象也可以用于实现线程同步,同时可以在进程之间使用
    */
    
    
    DWORD WINAPI myfunc1(LPVOID lpParam);
    DWORD WINAPI myfunc2(LPVOID lpParam);
    
    HANDLE hMutex;
    int a = 0;
    
    int main()
    {
        hMutex = ::CreateMutex(NULL,FALSE,NULL);
    
        HANDLE h1,h2;
        h1 = ::CreateThread(NULL,0,myfunc1,NULL,0,NULL);
        cout<<"线程1开始运行!"<<endl;
        h2 = ::CreateThread(NULL,0,myfunc2,NULL,0,NULL);
        cout<<"线程2开始运行!"<<endl;
        ::CloseHandle(h1);
        ::CloseHandle(h2);
        
        ::Sleep(10000);
        return 0;
    }
    
    DWORD WINAPI myfunc1(LPVOID lpParam)
    {
        while (TRUE)
        {
            ::WaitForSingleObject(hMutex,INFINITE);
            if(a < 10000)
            {
                a += 1;
                ::Sleep(1000);            
                cout<<"线程1:"<<a<<endl;
                ::ReleaseMutex(hMutex);
            }else
            {
                ::ReleaseMutex(hMutex);
                break;
            }
        }
    
        return 0;
    }
    DWORD WINAPI myfunc2(LPVOID lpParam)
    {
        while (TRUE)
        {
            ::WaitForSingleObject(hMutex,INFINITE);
            if(a < 10000)
            {
                a += 1;
                ::Sleep(1000);            
                cout<<"线程1:"<<a<<endl;
                ::ReleaseMutex(hMutex);
            }else
            {
                ::ReleaseMutex(hMutex);
                break;
            }
        }
    
        return 0;
    }

    3、互斥对象

    #include <Windows.h>
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    
    /*
      互斥对象
      互斥对象也可以用于实现线程同步,同时可以在进程之间使用
    */
    
    
    DWORD WINAPI myfunc1(LPVOID lpParam);
    DWORD WINAPI myfunc2(LPVOID lpParam);
    
    HANDLE hMutex;
    int a = 0;
    
    int main()
    {
        hMutex = ::CreateMutex(NULL,FALSE,NULL);
    
        HANDLE h1,h2;
        h1 = ::CreateThread(NULL,0,myfunc1,NULL,0,NULL);
        cout<<"线程1开始运行!"<<endl;
        h2 = ::CreateThread(NULL,0,myfunc2,NULL,0,NULL);
        cout<<"线程2开始运行!"<<endl;
        ::CloseHandle(h1);
        ::CloseHandle(h2);
        
        ::Sleep(10000);
        return 0;
    }
    
    DWORD WINAPI myfunc1(LPVOID lpParam)
    {
        while (TRUE)
        {
            ::WaitForSingleObject(hMutex,INFINITE);
            if(a < 10000)
            {
                a += 1;
                ::Sleep(1000);            
                cout<<"线程1:"<<a<<endl;
                ::ReleaseMutex(hMutex);
            }else
            {
                ::ReleaseMutex(hMutex);
                break;
            }
        }
    
        return 0;
    }
    DWORD WINAPI myfunc2(LPVOID lpParam)
    {
        while (TRUE)
        {
            ::WaitForSingleObject(hMutex,INFINITE);
            if(a < 10000)
            {
                a += 1;
                ::Sleep(1000);            
                cout<<"线程1:"<<a<<endl;
                ::ReleaseMutex(hMutex);
            }else
            {
                ::ReleaseMutex(hMutex);
                break;
            }
        }
    
        return 0;
    }
  • 相关阅读:
    BZOJ2144跳跳棋——LCA+二分
    BZOJ[Usaco2017 Jan]Promotion Counting——线段树合并
    BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
    BZOJ1559[JSOI2009]密码——AC自动机+DP+搜索
    BZOJ1222[HNOI2001]产品加工——DP
    [IOI2018]狼人——kruskal重构树+可持久化线段树
    BZOJ3091城市旅行——LCT区间信息合并
    Link-Cut Tree(LCT)&TopTree讲解
    BZOJ3669[Noi2014]魔法森林——kruskal+LCT
    BZOJ4530[Bjoi2014]大融合——LCT维护子树信息
  • 原文地址:https://www.cnblogs.com/jackStudy/p/5092094.html
Copyright © 2011-2022 走看看