zoukankan      html  css  js  c++  java
  • 【转】Mutex 和 Critical Section 的异同

    原作者:SAP 沧海 原文地址:http://www.cnblogs.com/omygod/archive/2006/11/08/554524.html

    MutexCritical Section都是主要用于限制多线程(Multithread)对全局或共享的变量、对象或内存空间的访问。下面是其主要的异同点(不同的地方用绿色表示)。

     

    Mutex

    Critical Section

    性能和速度

    慢。

    Mutex 是内核对象,相关函数的执行 (WaitForSingleObject,

    ReleaseMutex)需要用户模式(User Mode)到内核模式(Kernel Mode)的转换,在x86处理器上这种转化一般要发费600个左右的 CPU指令周期。

    快。

    Critical Section本身不是内核对象,相关函数(EnterCriticalSectionLeaveCriticalSection)的调用一般都在用户模式内执行,在x86处理器上一般只需要发费9个左右的 CPU指令周期。只有当想要获得的锁正好被别的线程拥有时才会退化成和Mutex一样,即转换到内核模式,发费600个左右的 CPU指令周期。

    能否跨越进程(Process)边界

    可以

    不可

    定义写法

    HANDLE hmtx;

    CRITICAL_SECTION cs;

    初始化写法

    hmtx= CreateMutex (NULL, FALSE, NULL);

    InitializeCriticalSection(&cs);

    结束清除写法

    CloseHandle(hmtx);

    DeleteCriticalSection(&cs);

    无限期等待的写法

    WaitForSingleObject (hmtx, INFINITE);

    EnterCriticalSection(&cs);

    0等待(状态检测)的写法

    WaitForSingleObject (hmtx, 0);

    TryEnterCriticalSection(&cs);

    任意时间等待的写法

    WaitForSingleObject (hmtx, dwMilliseconds);

    不支持

    锁释放的写法

    ReleaseMutex(hmtx);

    LeaveCriticalSection(&cs);

    能否被一道用于等待其他内核对象

    可以(使用WaitForMultipleObjectsWaitForMultipleObjectsEx,MsgWaitForMultipleObjects,MsgWaitForMultipleObjectsEx等等)

    不可

    当拥有锁的线程死亡时

    Mutex变成abandoned状态,其他的等待线程可以获得锁。

    Critical Section的状态不可知(undefined),以后的动作就不能保证了。

    自己会不会锁住自己

    不会(对已获得的Mutex,重复调用WaitForSingleObject不会锁住自己。但最后你别忘了要调用同样次数的ReleaseMutex

    不会(对已获得的Critical Section,重复调用EnterCriticalSection不会锁住自己。但最后你别忘了要调用同样次数的LeaveCriticalSection

     

    下面是一些补充:

    l         请先检查你的设计,把不必要的全局或共享对象改为局部对象。全局的东西越少,出问题的可能就越小。

    l         每次你使用EnterCriticalSection时,请不要忘了在函数的所有可能返回的地方都加上LeaveCriticalSection。对于Mutex也同样。若你把这个问题和Win32 structured exception或C++ exception一起考虑,你会发现问题并不是那么简单。自定义一个封装类可能是一种解决方案,以Critical Section为例的代码如下所示:

    class csholder

    {

        CRITICAL_SECTION *cs;

    public:

        csholder(CRITICAL_SECTION *c): cs(c)

        { EnterCriticalSection(cs); }

        ~csholder() { LeaveCriticalSection(cs); }

    };

     

    CRITICAL_SECTION some_cs;

    void foo()

    {

        // ...

        csholder hold_some(&some_cs);

     

        // ... CS protected code here

     

        // at return or if an exception happens

        // hold_some's destructor is automatically called

    }

    l         根据你的互斥范围需求的不同,把Mutex或Critical Section定义为类的成员变量,或者静态类变量。

    l         若你想限制访问的全局变量只有一个而且类型比较简单(比如是LONG或PVOID型),你也可以使用InterlockedXXX系列函数来保证一个线程写多个线程读。

     

     

    本文主要参照了Jeffrey Richter的《Programming Applications for Microsoft Windows, 4th Ed.》。

    SAP Tech. Consultant,专注于SAP SAP BW, SAP HANA.email:cn.yefei@yahoo.com SAP HANA项目实践及经验分享群: 146489445
  • 相关阅读:
    list1AndCompile
    pickle序列化2
    Servlet简单例子:输出当前日期
    Servlet简单例子:前后端通信
    Java 继承的简单例子
    Java 一个简单的距离工具类
    Java 私有静态成员变量的简单使用
    mysql数据类型
    使用Bootstrap简单案例——导航条+轮播图+模态框+表单
    K-means 聚类
  • 原文地址:https://www.cnblogs.com/gkwang/p/4482946.html
Copyright © 2011-2022 走看看