临界区、互斥量、信号量、事 件

临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
互斥量:为协调共同对一个共享资源的单独访问而设计的。
信号量:为控制一个具有有限数量用户资源而设计。
事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。






临界区:


    临界区最大线程是64.
    一般情况下,使用多线程都会使用CPP,因为CPP中有临界区结构.
    同时操作单一元素很容易产生冲突,这种时候就需要定义临界区.
    *临界区不是一个变量,而是调用操作系统,锁定当前变量.
    使用临界区需要使用CreateThread来创建线程.




    定义临界区:


        CRITICAL_SECTION cs;//临界区


            原型:
                struct CRITICAL_SECTION
                {
                    LONG lockCount;
                    LONG RecursionCount;
                    HANDLE OwningThread;
                    HANDLE LockSemaphore;
                    ULONG_PTR SpinCount;
                } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;




        InitializeCriticalSection(&cs); //初始化




        EnterCriticalSection(&cs); //进入临界区


        //... 变量操作内容




        LeaveCriticalSection(&cs);//离开临界区




        DeleteCriticalSection(&cs); //删除临界区




事件:
        createEvent(); //创建事件


            HANDLE CreateEvent(
               PSECURITY_ATTRIBUTES psa,  //安全描述符,瞧,这是个内核对象
               BOOL fManualReset,
               BOOL fInitialState,
               PCTSTR pszName);


           fManualReset参数为TRUE时,表示创建一个人工重置的时间,为FALSE时表示创建一个自动重置事件。
           fInitialState参数为TRUE时,指明该事件是要初始化为已通知状态,反之为未通知状态。
           pszName 时间名称


        OpenEvent(EVENT_ALL_ACCSEE,true,name); //打开事件


            HANDLE OpenEvent(
               DWORD fdwAccess,
               BOOL fInherit,
               PCTSTR pszName);




            pszName 时间名称




        SetEvent(); //设置信号启用
        ResetEvent(); //复位信号
    实例:


        HANDLE event[3] = {0}; //事件
        HANDLE hthread[3] = {0}; //线程


        DWORD WINAPI firstthread(void *p)
        {
            SetEvent(event[0]);


            return 0;
        }


        DWORD WINAPI secondthread(void *p)
        {
            WaitForSingleObject(event[0], INFINITE);// 等待信号
            //...


            ResetEvent(event[0]);
            return 0;
        }


        void main()
        {
            //创建事件
            event[0] = createEvent(NULL, TRUE, FLASH, NULL);
            event[1] = createEvent(NULL, TRUE, FLASH, NULL);




            hthread[0] = CreateThread(NULL, 0, firstthread, NULL, 0, NULL);
            hthread[1] = CreateThread(NULL, 0, secondthread, NULL, 0, NULL);




            WaitForMultipleObjects(2, hthread, true, INFINI);
            printf("全部完成\n");


            system("pause");
        }




互斥量:


        CreateMutex(); //创建互斥量
        CreateMutex(NULL, FALSH, NULL);
            参数1: 安全机制
            参数2: 是否激活


        ReleaseMutex(mutex); //注销互斥量


        OpenMutex(MUTEX_ALL_ACCESS, TRUE, name); 打开互斥量


        实例:


        HANDLE mutex= NULL;




        DWORD WINAPI add(void *p)
        {
            WaitForSingleObject(mutex, INFINITE);
            int i = 0;
            while(++i != 101)
            {
                num++;
            }
            ReleaseMutex(mutex);
        }


        void main()
        {


            mutex = CreateMutex(NULL, Flash, NULL);
            HANDLE hd[64];
            int i;
            for (i = 0, i < 64; i++)
            {
                hd[i] = CreadThread(NULL, 0, add, NULL, 0, NULL);
            }


            WaitForMultipleObjects(64, hd, true, INFINITE);




            for (i = 0, i < 64; i++)
            {
                CloseHandle(hd[i]);
            }
            system("pause");
        }






原子操作:
    原子操作可以理解为在寄存器中直接操作,速度快,可以避免多线程中的一些问题


    原子操作的速度要快于互斥量,临界区,event


    InterlockedIncrement(&num); //变量++操作
    InterlockedExchangeAnd(&num, 1); //num++
    InterlockedDecrement(&num); //num--
    InterlockedExchange(); //改变
    InterlockedAnd(&num, 1); // num + 1






时间同步:


    单独定时器只能用在同步通信


    SetWaitablesTimer(timer, &time, 0, NULL, 0 NULL)
        参数3: 多少毫秒一次
        参数4: 回调函数
        参数5: 参数


        回调函数声明格式:
            //参数2与参数3是时差
            void CALLBACK timerun(viod *parg, DWORD timeaeg, DWORD timehigh)
            {


            }


        CamcelWaitableTimer(timer);//取消定时器


    定时器:
        //创建定时器
        HANDLE timer = CreateWaitableTimer(NULL, TRUE, 'name');


        if (timer == NULL)
            return 0;




        LARGE_INTEGER time; //可精确到小数点后7位


        time.Quadpart = -2000000 // 2秒


        SetWaitablesTimer(timer, &time, 0, NULL, 0 NULL);//设置定时器等待


        if (WaitForSingleObject(timer, INFINITE) == WAIT_OBJECT_0)
        {
            print("等待成功");
        }




信号:


    HANDLE hdsm = CreateSemaphore(NULL, 0, 3, 'haihua'); //开辟一个信号,最大计数是3
    HANDLE myhsem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, flash, 'haihua'); //打开信号
        SEMAPHORE_ALL_ACCESS 全部


    closeHandle(hdsm); //注销




    实例:


        DWORD WINAPI myworker(void *p)
        {
            int *pint = p;


            HANDLE myhsem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, flash, 'eli');


            if (myhsem)
            {
                if (WaitForSingleObject(myhsem, INFINITE) == WAIT_OBJECT_0)
                {
                    //...
                }
                ReleaseSemaphore(myhsem, 1,NULL);//释放资源
                CloseHandle(myhsem); //退出线程
            }
        }


        void main()
        {
            HANDLE hSEM = CreateSemaphoree(NULL, 0, 3, 'eli');
            int a[10] = {0,1,2,3,4,5,6,7,8,9};
            HANDLE hd[10] = {0};
            int i;
            for (i = 0; i < 10; i++)
            {
                hd[i] = CreateThread(NULL, 0, myworker, a+i, 0, NULL);
            }
            sleep(2000);


            printf("激活线程");


            ReleaseSemaphore(hSEM,3,NULL);//激活


            WaitForMultipleObject(10, hd, true, INFINITE);




            closeHandle(hSEM);
        }






互斥锁:


    SRWLOCK g_lock;


    第一个 InitializeSRWLock


    函数功能:初始化读写锁
    函数原型:VOID InitializeSRWLock(PSRWLOCK SRWLock);
    函数说明:初始化(没有删除或销毁SRWLOCK的函数,系统会自动清理)




    第二个 AcquireSRWLockExclusive


    函数功能:写入者线程申请写资源。
    函数原型:VOID AcquireSRWLockExclusive(PSRWLOCK SRWLock);




    第三个 ReleaseSRWLockExclusive


    函数功能:写入者线程写资源完毕,释放对资源的占用。
    函数原型:VOID ReleaseSRWLockExclusive(PSRWLOCK SRWLock);




    第四个 AcquireSRWLockShared


    函数功能:读取者线程申请读资源。
    函数原型:VOID AcquireSRWLockShared(PSRWLOCK SRWLock);


    第五个 ReleaseSRWLockShared


    函数功能:读取者线程结束读取资源,释放对资源的占用。
    函数原型:VOID ReleaseSRWLockShared(PSRWLOCK SRWLock);


    注意一个线程仅能锁定资源一次,不能多次锁定资源。




    实例:


        int num = 0;
        SRWLOCK g_lock;


        DWORD WINAPI myworker(void *p) //写
        {
            AcquireSRWLockExclusive(&num);
            while(++i != 101)
            {


                num++;
            }
            ReleaseSRWLockExclusive(&num);
        }


        DWORD WINAPI read(void *p) //读写
        {
            AcquireSRWLockShared(&num);
            while(++i != 101)
            {


                num++;
            }
            ReleaseSRWLockShared(&num);
        }


        void main()
        {


            InitializeSRWLock(&num);
            HANDLE hd[10] = {0};
            CreateThread(NULL, 0, read, NULL, 0, NULL);


            int i;
            for (i = 0; i < 10; i++)
            {
                hd[i] = CreateThread(NULL, 0, myworker, NULL, 0, NULL);
            }


            WaitForMultipleObject(10, hd, true, INFINITE);




            closeHandle(hSEM);
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值