关于两个进程CreateMutex创建同名互斥体

ooolinux 2016-08-06 02:36:46
如果一个进程A(线程A):HANDLE hMutexA=CreateMutex(NULL,true,"MyAppMutex"); 创建了一个互斥体,
然后另一个进程B(线程B)也:HANDLE hMutexB=CreateMutex(NULL,true,"MyAppMutex"); 创建了一个同名互斥体,
1、这个时候hMutexB会得到已经存在的互斥体的句柄吗?
2、这个时候互斥体由线程A拥有还是线程B拥有?
3、假如由线程B拥有,线程A会挂起吗?
4、如果线程B此时ReleaseMutex(hMutexB),线程A会重新获取互斥体并转为就绪态吗?
5、如果线程B不ReleaseMutex(hMutexB),而是CloseHandle(hMutexB),线程A会处于什么运行状态?
问题有点多,谢谢!
...全文
715 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ooolinux 2016-08-08
  • 打赏
  • 举报
回复
引用 10 楼 lm_whales 的回复:
MFC 创建内核对象,和检测代码。 都写在 WinApp 的派生类的构造函数 或者他的InitInstance(); 没创建成功,直接调用 exit退出 创建成功,如果已经存在,也可以直接退出 如果可能,你也可以把一些信息,传递给上一个实例,不过这和 Mutex关系不大了 创建成功,并且是第一个实例,就可以做事情了 抱歉,摘抄的帮助,没整理直接发过来了 GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. 意思是说,这个内核对象 hMutexB 只是获得同一个内核对象的句柄。 但是线程并没有理所当然的获得内核对象的所有权。 依然需要依赖等待函数,才能拥有 Mutex 的所有权。 也就是说,同步还是需要倚靠 wait,release 很函数,而不是打开方式 不过这和 利用内核对象,确认 进程有无实例运行没有关系了 只要 GetLastError returns ERROR_ALREADY_EXISTS,就表明。这个内核对象,已经存在了。 如果别的程序,不使用同名, 同一类型内核对象的话,就可以确定是同一个程序的不同实例了。 这里的前提是bInitialOwner is ignored,如果不是被忽略的话, 而是第一次成功创建内核对象--- 返回值不是 ERROR_ALREADY_EXISTS ----- bInitialOwner可以决定,线程创建内核对象,立即就拥有它的所以权,其他线程, 必须等候该线程释放 Mutex 的所有权。 才可以拥有(等到)他的所有权。
现在我清楚了
引用 6 楼 lm_whales 的回复:
微软的实例

/*******
Using Named Objects
The following example illustrates the use of object names by creating and opening a named mutex.

First Process
The first process uses the CreateMutex function to create the mutex object. Note that this function succeeds even if there is an existing object with the same name.
***************/

#include <windows.h>
#include <stdio.h>
#include <conio.h>

// This process creates the mutex object.

void main()
{
    HANDLE hMutex; 

    hMutex = CreateMutex( 
        NULL,                        // default security descriptor
        FALSE,                       // mutex not owned
        TEXT("NameOfMutexObject"));  // object name,这是直接写名字的,名字还可以有Gloabal\和Loacal\前缀

    if (hMutex == NULL) 
        printf("CreateMutex error: %d\n", GetLastError() ); //这种时候,啥也不能做,只好推出了
    else 
        if ( GetLastError() == ERROR_ALREADY_EXISTS ) //这表明 hMutex已经创建了,也就是进程已经有个实例在运行了
            printf("CreateMutex opened an existing mutex\n"); // 你的程序,这这时候退出,就可以了,注意随手CloseHandle
        else printf("CreateMutex created a new mutex.\n");//否则,这是第一个实例,下面就可以开工干活了
//........... 开工干活,MFC可以写在WinAPP 的派生类的构造函数中
    // Keep this process around until the second process is run
    _getch();
}
/***************
Second Process
The second process uses the OpenMutex function to open a handle to the existing mutex. This function fails if a mutex object with the specified name does not exist. The access parameter requests full access to the mutex object, which is necessary for the handle to be used in any of the wait functions.


#include <windows.h>
#include <stdio.h>

// This process opens a handle to a mutex created by another process.
*****************/
void main()
{
    HANDLE hMutex; 

    hMutex = OpenMutex( 
        MUTEX_ALL_ACCESS,            // request full access
        FALSE,                       // handle not inheritable
        TEXT("NameOfMutexObject"));  // object name

    if (hMutex == NULL) 
        printf("OpenMutex error: %d\n", GetLastError() );
    else printf("OpenMutex successfully opened the mutex.\n");
}
随手CloseHandle确实是好习惯
lm_whales 2016-08-08
  • 打赏
  • 举报
回复
bInitialOwner 参数为TRUE表示创建即拥有 为FALSE 表示创建不拥有,而是需要依赖等待函数取得所有权。
lm_whales 2016-08-08
  • 打赏
  • 举报
回复
MFC 创建内核对象,和检测代码。 都写在 WinApp 的派生类的构造函数 或者他的InitInstance(); 没创建成功,直接调用 exit退出 创建成功,如果已经存在,也可以直接退出 如果可能,你也可以把一些信息,传递给上一个实例,不过这和 Mutex关系不大了 创建成功,并且是第一个实例,就可以做事情了 抱歉,摘抄的帮助,没整理直接发过来了 GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. 意思是说,这个内核对象 hMutexB 只是获得同一个内核对象的句柄。 但是线程并没有理所当然的获得内核对象的所有权。 依然需要依赖等待函数,才能拥有 Mutex 的所有权。 也就是说,同步还是需要倚靠 wait,release 很函数,而不是打开方式 不过这和 利用内核对象,确认 进程有无实例运行没有关系了 只要 GetLastError returns ERROR_ALREADY_EXISTS,就表明。这个内核对象,已经存在了。 如果别的程序,不使用同名, 同一类型内核对象的话,就可以确定是同一个程序的不同实例了。 这里的前提是bInitialOwner is ignored,如果不是被忽略的话, 而是第一次成功创建内核对象--- 返回值不是 ERROR_ALREADY_EXISTS ----- bInitialOwner可以决定,线程创建内核对象,立即就拥有它的所以权,其他线程, 必须等候该线程释放 Mutex 的所有权。 才可以拥有(等到)他的所有权。
lm_whales 2016-08-07
  • 打赏
  • 举报
回复
Using Named Objects The following example illustrates the use of object names by creating and opening a named mutex. First Process The first process uses the CreateMutex function to create the mutex object. Note that this function succeeds even if there is an existing object with the same name. #include <windows.h> #include <stdio.h> #include <conio.h> // This process creates the mutex object. void main() { HANDLE hMutex; hMutex = CreateMutex( NULL, // default security descriptor FALSE, // mutex not owned TEXT("NameOfMutexObject")); // object name if (hMutex == NULL) printf("CreateMutex error: %d\n", GetLastError() ); else if ( GetLastError() == ERROR_ALREADY_EXISTS ) printf("CreateMutex opened an existing mutex\n"); else printf("CreateMutex created a new mutex.\n"); // Keep this process around until the second process is run _getch(); } Second Process The second process uses the OpenMutex function to open a handle to the existing mutex. This function fails if a mutex object with the specified name does not exist. The access parameter requests full access to the mutex object, which is necessary for the handle to be used in any of the wait functions. #include <windows.h> #include <stdio.h> // This process opens a handle to a mutex created by another process. void main() { HANDLE hMutex; hMutex = OpenMutex( MUTEX_ALL_ACCESS, // request full access FALSE, // handle not inheritable TEXT("NameOfMutexObject")); // object name if (hMutex == NULL) printf("OpenMutex error: %d\n", GetLastError() ); else printf("OpenMutex successfully opened the mutex.\n"); }
lm_whales 2016-08-07
  • 打赏
  • 举报
回复
CreateMutex Function Creates or opens a named or unnamed mutex object. To specify an access mask for the object, use the CreateMutexEx function. HANDLE WINAPI CreateMutex( __in LPSECURITY_ATTRIBUTES lpMutexAttributes, __in BOOL bInitialOwner, __in LPCTSTR lpName ); Parameters lpMutexAttributes A pointer to a SECURITY_ATTRIBUTES structure. If this parameter is NULL, the handle cannot be inherited by child processes. The lpSecurityDescriptor member of the structure specifies a security descriptor for the new mutex. If lpMutexAttributes is NULL, the mutex gets a default security descriptor. The ACLs in the default security descriptor for a mutex come from the primary or impersonation token of the creator. For more information, see Synchronization Object Security and Access Rights. bInitialOwner If this value is TRUE and the caller created the mutex, the calling thread obtains initial ownership of the mutex object. Otherwise, the calling thread does not obtain ownership of the mutex. To determine if the caller created the mutex, see the Return Values section. lpName The name of the mutex object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. If lpName matches the name of an existing named mutex object, this function requests the MUTEX_ALL_ACCESS access right. In this case, the bInitialOwner parameter is ignored because it has already been set by the creating process. If the lpMutexAttributes parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored. If lpName is NULL, the mutex object is created without a name. If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space. The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces. Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users. Windows 2000: If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character. The object can be created in a private namespace. For more information, see Object Namespaces. Return Value If the function succeeds, the return value is a handle to the newly created mutex object. If the function fails, the return value is NULL. To get extended error information, call GetLastError. If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.
ooolinux 2016-08-07
  • 打赏
  • 举报
回复
引用 1 楼 anhuizhuanjiao 的回复:
写出来试试不就知道了
引用 2 楼 lm_whales 的回复:
命名内核对象(同一用户)只会创建一份。 似乎是这样的 命名内核对象 是全局的,不允许重名 非命名 内核对象,是进程局部的 进程间通讯,可以用命名内核对象。
事实上,是一个程序要防止二次启动,不知道代码怎么写比较正确,因为对几个函数不太理解。
lm_whales 2016-08-07
  • 打赏
  • 举报
回复
命名内核对象(同一用户)只会创建一份。 似乎是这样的 命名内核对象 是全局的,不允许重名 非命名 内核对象,是进程局部的 进程间通讯,可以用命名内核对象。
ooolinux 2016-08-07
  • 打赏
  • 举报
回复
引用 8 楼 pengzhixi 的回复:
If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.
也就是说hMutexB得到已经存在的互斥体对象的句柄,对象使用计数加一? and the calling thread is not granted ownership 但是线程B不会拥有互斥体?
pengzhixi 2016-08-07
  • 打赏
  • 举报
回复
If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.
lm_whales 2016-08-07
  • 打赏
  • 举报
回复
微软的实例

/*******
Using Named Objects
The following example illustrates the use of object names by creating and opening a named mutex.

First Process
The first process uses the CreateMutex function to create the mutex object. Note that this function succeeds even if there is an existing object with the same name.
***************/

#include <windows.h>
#include <stdio.h>
#include <conio.h>

// This process creates the mutex object.

void main()
{
    HANDLE hMutex; 

    hMutex = CreateMutex( 
        NULL,                        // default security descriptor
        FALSE,                       // mutex not owned
        TEXT("NameOfMutexObject"));  // object name,这是直接写名字的,名字还可以有Gloabal\和Loacal\前缀

    if (hMutex == NULL) 
        printf("CreateMutex error: %d\n", GetLastError() ); //这种时候,啥也不能做,只好推出了
    else 
        if ( GetLastError() == ERROR_ALREADY_EXISTS ) //这表明 hMutex已经创建了,也就是进程已经有个实例在运行了
            printf("CreateMutex opened an existing mutex\n"); // 你的程序,这这时候退出,就可以了,注意随手CloseHandle
        else printf("CreateMutex created a new mutex.\n");//否则,这是第一个实例,下面就可以开工干活了
//........... 开工干活,MFC可以写在WinAPP 的派生类的构造函数中
    // Keep this process around until the second process is run
    _getch();
}
/***************
Second Process
The second process uses the OpenMutex function to open a handle to the existing mutex. This function fails if a mutex object with the specified name does not exist. The access parameter requests full access to the mutex object, which is necessary for the handle to be used in any of the wait functions.


#include <windows.h>
#include <stdio.h>

// This process opens a handle to a mutex created by another process.
*****************/
void main()
{
    HANDLE hMutex; 

    hMutex = OpenMutex( 
        MUTEX_ALL_ACCESS,            // request full access
        FALSE,                       // handle not inheritable
        TEXT("NameOfMutexObject"));  // object name

    if (hMutex == NULL) 
        printf("OpenMutex error: %d\n", GetLastError() );
    else printf("OpenMutex successfully opened the mutex.\n");
}
转角天边 2016-08-06
  • 打赏
  • 举报
回复
写出来试试不就知道了

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧