`
hanyezhiyu8
  • 浏览: 153894 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

关于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。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics