zoukankan      html  css  js  c++  java
  • 所有同步方法

    1. 线程同步

     问题:多个线程对同一个回调函数操作,导致一段代码未执行完就开始切换下一个线程,造成数据混乱。为了不造成混乱,使用了限定操作 同步

    1.1 原子操作 -- 单值

    Interlocked function  函数里有关原子操作

    互锁函数同步对多个线程共享的变量的访问。它们的目的是防止线程在递增或检查变量时被抢占。不同进程的线程可以使用这些函数,因为它们的变量共享内存。Windows CE支持三个互锁函数

    InterlockedIncrement 增加一个共享变量并检查结果值

    InterlockedDecrement 递减共享变量并检查结果值

    InterlockedExchange 交换指定变量的值

    InterlockedTestExchange 只有当其中一个变量是特定的,才交换指定变量的值

           InterlockedExchangeAdd -- 加法操作不可打断

    InterlockExchangeAdd函数向addend变量执行增量值的原子加法。该函数防止多个线程同时使用同一个变量。

    1.2 关键段

    使用关键段首先先要定义一个结构体变量

    CRITICAL_SECTION  cs;

    这是一个传出变量

      //初始化关键段

      InitializeCriticalSection(&cs);

    //如果锁着,则等待,如果没有锁着,则返回, 并上锁

           EnterCriticalSection(&cs)

              在同一个线程调用,会增加引用计数,几次enter,需要对应次数的leave

     //解锁,让出所有权

           LeaveCriticalSection(&cs);

     EnterCriticalSection(&cs)和LeaveCriticalSection(&cs)必须成对使用;

     

           TryEnterCriticalSection(&cs);  有返回值

              TRUE,进入关键段,并上锁

              FALSE,其他线程在使用

           LeaveCriticalSection(&cs)

    TryEnterCriticalSection和EnterCriticalSection使用方式相同 不过有一个BOOL的返回值表示是否获得所有权

           

           InitializeCriticalSection(&cs); 初始化

     

           DeleteCriticalSection(&cs);  反初始化

    1.3 内核同步对象(事件, 信号灯, 互斥体)

       在多线程的情况下,有时候我们会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用Windows API函数WaitForSingleObject,或者WaitForMultipleObjects。这两个函数都会等待Object被标为有信号(signaled)时才返回的。

    那么,信号是什么呢?首先我们可以假设这里存在一个文件和两个线程,我们规定这个文件同一时刻只能被一个线程所访问打开,那么我们的线程该如何知道这个文件现在有没有被别的线程访问呢?我们可以让线程等在一个死循环里,这个循环之一在尝试打开访问这个文件,直到能够打开为止;这样做虽然可以实现目的,但是死循环会占用大量的内存,所以windows就设置了信号量。信号量的作用简单理解就是一个标志位,在我们上述的问题中,这个文件就有一个信号量,初始时我们设信号量为FALSE,而只有当信号量为FALSE时线程才可以打开访问这个文件。那么,当第一个线程到达,信号量为FALSE,线程打开文件进行访问,并将信号量置为TRUE;在第一个线程在访问文件时,第二个线程到来,此时信号量仍未TRUE,所以第二个线程等待,这个等待的过程就是WaitForSingleObjectWaitForSingleObject在等待的过程中会进入一个非常高效的沉睡等待状态,只占用极少的CPU时间片。

           state(状态)

               signaled -- 已触发, 开锁

               no-signal -- 未触发, 关锁

           process/线程

              signaled -- 结束运行

              no-signal -- 正在运行   

           

          检测方式:

    WaitForSingleObject等待的对象Event,Mutex,Semaphore,Process,Thread 

    有三种返回类型:

    WAIT_OBJECT_0, 表示等待的对象有信号(对线程来说,表示执行结束);

     WAIT_TIMEOUT, 表示等待指定时间内,对象一直没有信号(线程没执行完);

    WAIT_ABANDONED 表示对象有信号,但还是不能执行  一般是因为未获取到锁或其他原因

          WaitForSingleObject -- 等待一个对象

    DWORD WaitForSingleObject(

    HANDLE hHandle, // handle to object     对象句柄 可以是信号或者进程

     DWORD dwMilliseconds // time-out interval);等待时间

    INFINITE    一直等时间结束 宏的值为-1

     

              WaitForMultipleObjects  -- 等待多个对象

    DWORD WaitForMultipleObjects(

    DWORD nCount, // number of handles in array    个数

    CONST HANDLE *lpHandles, // object-handle array 句柄数组

     BOOL bWaitAll, // wait option 等待选项

     DWORD dwMilliseconds // time-out interval);等待时间

    1.4 事件(event)

    事件对象就像一个开关:它只有两种状态---开和关。当一个事件处于”开”状态,我们称其为”有信号”否则称为”无信号”。可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是”无信号”就让该线程睡眠,这样该线程占用的CPU时间就比较少。

     一个Event被创建以后,可以

    OpenEvent()API来获得它的Handle

    CloseHandle() 来关闭它,

    SetEvent()或PulseEvent()来设置它使其有信号,

    ResetEvent()来使其无信号,

    WaitForSingleObject()或WaitForMultipleObjects()来等待其变为有信号. 

      

          CreateEvent -- 创建事件对象

    HANDLECreateEvent(

    LPSECURITY_ATTRIBUTESlpEventAttributes,  // 安全属性

    BOOLbManualReset, // 复位方式 true表示 手工设置触发和未触发  false表示默认系统设置  一般系统直接设置为未触发状态

    BOOLbInitialState, // 初始状态  true表示开始触发

    LPCTSTRlpName // 对象名称 若是本进程使用不需要跨进程  跨进程配合OpenEvent使用

    );

          SetEvent  -- 将事件对象设置为已触发(开锁)状态

          ResetEvent -- 将事件对象设置为未触发(关锁)状态

          OpenEvent -- 通过名字打开一个事件对象

    HANDLEOpenEvent(

    DWORD dwDesiredAccess,EVENT_ALL_ACCESS 指定事件对象所有可能的权限

    BOOL bInheritHandle,句柄是否继承 

    LPCTSTR lpName即将要打开的事件对象的名字

    );

    学如逆水行舟,不进则退。 博客园技术交流群 群 号:1073255314 (本群没人,刚刚建立 -_-!!! )
  • 相关阅读:
    vs 视图其它窗口命令窗口
    WPF 翻转动画实现(转)
    ASP.NET的后台代码和前台JS代码相互调用
    LINQ学习心得分享(三)LINQ语法详解2
    LINQ学习心得分享(二)LINQ语法详解
    《AJAX学习心得分享(三)AJAX+JSON无刷新加载大量后台数据》
    A simple poem
    LINQ学习心得分享(五)LINQ TO SQL实用详解
    LINQ学习心得分享(四)LINQ TO XML实用解析
    AJAX学习心得分享(一)AJAX初识+原生态AJAX
  • 原文地址:https://www.cnblogs.com/Mj-NaijAm/p/13615489.html
Copyright © 2011-2022 走看看