2011-09-25 95 views
0

我有互斥 我有这样的代码,我不知道为什么它不能正常工作的问题...互斥问题

#include <windows.h> 
#include <process.h> 
#include <stdio.h> 
HANDLE mutex; 
unsigned _stdcall t(void*){ 
printf(":D:D:D\n"); 
return NULL; 
} 
int main(){ 
mutex=CreateMutex(NULL,FALSE,NULL); 
WaitForSingleObject(mutex,INFINITE); 
_beginthreadex(NULL,NULL,&t,NULL,0,NULL); 
WaitForSingleObject(mutex,INFINITE); 
printf("HD\n"); 
} 

结果是:

HD 
:D:D:D 

我不希望看到在控制台HD .....

但是这个代码正常工作

HANDLE mutex; 
unsigned _stdcall t(void*){ 
WaitForSingleObject(mutex,INFINITE); 
printf(":D:D:D\n"); 
ReleaseMutex(mutex); 
return NULL; 
} 
int main(){ 
mutex=CreateMutex(NULL,FALSE,NULL); 
WaitForSingleObject(mutex,INFINITE); 
_beginthreadex(NULL,NULL,&t,NULL,0,NULL); 
printf("HD\n"); 
while(1){ 
} 

} 

结果是:

HD 

谢谢大家....

+4

请经常检查WaitForSingleObject和其他核心函数的返回值。如果不这样做,您将永远无法调试自己的代码。 – Mat

回答

6

MSDN

拥有互斥可以指定反复等待功能相同的互斥体的线程调用而不会阻止其执行。

因此,在您的第一个示例中,第二次调用WaitForSingleObject()不会阻塞主线程,因为它是拥有该互斥量的线程。

+0

有任何建议,可以在这种情况下工作?我的意思是一个例子... – pooya

+0

@pooya:你想达到什么?如果它只是不打印“HD”,我只是不打印它 - 你已经知道你拥有互斥锁(给予适当的返回值检查)。 –

+0

我想在opengl程序中使用这个互斥体... – pooya

5

它看起来像你想主线程代表辅助线程采取互斥体。互斥体是通过线程跟踪的,因此您不能代表其他人进行互斥。您可能想切换到没有所有者跟踪的信号灯。

0

您使用了不当的互斥锁:当您等待互斥锁时,您会阻止,直到其他人释放它。

线程过程必须在主线程中执行自己的锁/解锁(Windows中的WaitForSingleObject和ReleaseMutex)。 目的是避免一个线程将输出与另一个线程交错。

如果你想“加入”一个线程(终止后做一些事情),你也可以等待它。

HANDLE mutex; 

unsigned _stdcall t(void*) 
{ 
    WaitForSingleObject(mutex,INFINITE); 
    printf(":D:D:D\n"); 
    ReleaseMutex(mutex); 
    return NULL; 
} 

int main() 
{ 
    mutex=CreateMutex(NULL,FALSE,NULL); 
    _beginthreadex(NULL,NULL,&t,NULL,0,NULL); 
    Sleep(0); 
    WaitForSingleObject(mutex,INFINITE); 
    printf("HD\n"); 
    ReleaseMutex(mutex); 
} 

另外:不要使用无限循环卡住线程(while(1) ...),使用Sleep代替。

另请注意,通常情况下,您无法预测首先将打印哪个线程。这就是并发性:线程互相竞争并行运行。互斥体避免它们一起输出,但是会产生什么序列还取决于系统在运行程序时还在做什么。