关于Mutex的使用问题

权限问题

 

互斥量对象会一直存活着直到使用它的最后一个程序关闭其句柄,因此它能在初始创建它的应用程序退出后保留相当长的时间。因为此对象被广泛地共享,所以它必须被赋予明确的许可以允许任何人使用它。事实上,“缺省”许可几乎从不适用。 对于 SYNCHRONIZE和MUTEX_ALL_ACCESS 权限,因为非管理员没有这些权限(仅有上列的少许)互斥量不能被打开或者获取,于是CreateMutex() 和OpenMutex() 返回NULL。因此,当对象已经存活于内存中时硬性改变其上的许可配置:(需要调用 SetKernelObjectSecurity(),下列程序片断展示一个程序如何才能打开互斥量并安装一个新的 DACL,此 DACL 即使在程序退出后也仍然保持着,只要任一其他程序还维护有它的句柄)

...
                        // open the mutex that we're going to adjust
                        HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "DBWinMutex");
                        // create SECURITY_DESCRIPTOR with an explicit, empty DACL
                        // that allows full access to everybody
                        SECURITY_DESCRIPTOR     sd;
                        InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
                        SetSecurityDescriptorDacl(
                        &sd,            // addr of SD
                        TRUE,           // TRUE=DACL present
                        NULL,           // ... but it's empty (wide open)
                        FALSE);         // DACL explicitly set, not defaulted
                        // plug in the new DACL
                        SetKernelObjectSecurity(hMutex, DACL_SECURITY_INFORMATION, &sd);
                        ...

 

例子:

 

HANDLE hEventQuit = NULL;
hEventQuit = CreateEvent(NULL, FALSE, FALSE, NULL);

DWORD WINAPI ThreadOperation()
{
    HANDLE hMutex = NULL;

    // Create SECURITY_DESCRIPTOR with an explicit, empty DACL
    // that allows full access to everybody
    SECURITY_DESCRIPTOR sd;
    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(
        &sd,            // addr of SD
        TRUE,           // TRUE=DACL present
        NULL,           // ... but it's empty (wide open)
        FALSE);         // DACL explicitly set, not defaulted

    // Open the mutex that we're going to adjust
    hMutex = OpenMutex(MUTEX_ALL_ACCESS, NULL, _T("Global\\MutexName"));
    if (NULL == hMutex)
    {
        SECURITY_ATTRIBUTES sa;
        sa.nLength = sizeof(sa);
        sa.bInheritHandle = FALSE;
        sa.lpSecurityDescriptor = &sd;
        hMutex = CreateMutex(&sa, FALSE, _T("Global\\MutexName"));
    }
    // Plug in the new DACL
    SetKernelObjectSecurity(hMutex, DACL_SECURITY_INFORMATION, &sd);

    if (NULL != hMutex)
    {
        HANDLE hMutexHandles[] = {hMutex, hEventQuit};
        DWORD dwMutexResult = WaitForMultipleObjects(
            _countof(hMutexHandles), 
            hMutexHandles, 
            FALSE, 
            INFINITE);
        switch(dwMutexResult)
        {
        case WAIT_OBJECT_0:     //scucess
            //Do yourself things            
            break;
        case WAIT_OBJECT_0 + 1: //quit,cancel thread
            break;
        case WAIT_ABANDONED:
            //not release mutex and not response
            break;
        default:    //failure
            //decide operation yourself
            break;
        }
        ReleaseMutex(hMutex);
    }
    else
    {
        CloseHandle(hMutex); 
    }

    return 0;
}

 

 

延伸:

 

互斥对象

 

1. 互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。

 

2. 互斥对象包含一个使用数量,一个线程ID和一个计数器。

 

3. ID用于标识系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。

 

涉及到三个函数:

 

1. CreateMutex:创建互斥对象,返回互斥对象的句柄,其中第二个参数如果是TRUE,表示调用该函数的线程拥有互斥对象的所有权,即互斥对象处于非空闲状态。如果是FALSE,则表示当前互斥对象处于空闲状态,其他线程可以占用。

 

2. WaitForSingleObject(WaitForMultipleObject):等待互斥对象的使用权,如果第二个参数设置为INFINITE,则表示会持续等待下去,直到拥有所有权,才有权执行该函数下面的语句。一旦拥有了所有权,则会将互斥对象的的线程ID设置为当前使用的线程ID值。

 

3. ReleaseMutex:将互斥对象所有权进行释放,交还给系统。

 

可以将互斥对象想象成一把钥匙,CreateMutex创建了这把钥匙,WaitForSingleObject等待这把钥匙去访问一个公共的资源,比如一个房间,如果拥有了钥匙,则这个房间的所有权就属于这个进程了,别人是进不去这个房间的,直到进程将这个房间的钥匙归还掉,即ReleaseMutex。


访问控制项 (ACE)
安全描述符 (SD)
随机访问控制列表 (DACL)

 

当允许访问的 ACE 被添加到文件的随机访问控制列表 (DACL) 中时,相应用户或组帐户与 ACE 关联将由提供与该文件允许访问系统。大多数的情况文件的 DACL 不足够大,以添加更多的 ACE。因此,就需要创建一个新的访问控制列表 (ACL) 和从该文件的现有 DACL 按首选顺序复制ace。新的 DACL 然后可以替换该文件的安全描述符 (SD) 中旧的 DACL。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值