[英]Mutex can't acquire lock
我有一個問題,我的功能之一無法獲取我使用的2個互斥鎖之一上的鎖。 我在VC ++ 2010中進行了基本調試,設置了一些斷點,並且似乎在任何地方獲得了鎖都可以將其解鎖。
使用互斥鎖的代碼如下:
#define SLEEP(x) { Sleep(x); }
#include<windows.h>
void Thread::BackgroundCalculator( void *unused ){
while( true ){
if(MUTEX_LOCK(&mutex_q, 5) == 1){
if(!QueueVector.empty()){
//cut
MUTEX_UNLOCK(&mutex_q);
//cut
while(MUTEX_LOCK(&mutex_p,90000) != 1){}
//cut
MUTEX_UNLOCK(&mutex_p);
}
}
SLEEP(25);
}
}
然后在其他地方:
PLUGIN_EXPORT void PLUGIN_CALL
ProcessTick(){
if(g_Ticked == g_TickMax){
if(MUTEX_LOCK(&mutex_p, 1) == 1){
if(!PassVector.empty()){
PassVector.pop();
}
MUTEX_UNLOCK(&mutex_p);
}
g_Ticked = -1;
}
g_Ticked += 1;
}
static cell AMX_NATIVE_CALL n_CalculatePath( AMX* amx, cell* params ){
if(MUTEX_LOCK(&mutex_q,1) == 1){
QueueVector.push_back(QuedData(params[1],params[2],params[3],amx));
MUTEX_UNLOCK(&mutex_q);
return 1;
}
return 0;
}
在里面:
PLUGIN_EXPORT bool PLUGIN_CALL Load( void **ppData ) {
MUTEX_INIT(&mutex_q);
MUTEX_INIT(&mutex_p);
START_THREAD( Thread::BackgroundCalculator, 0);
return true;
}
一些變量和函數:
int MUTEX_INIT(MUTEX *mutex){
*mutex = CreateMutex(0, FALSE, 0);
return (*mutex==0);
}
int MUTEX_LOCK(MUTEX *mutex, int Timex = -1){
if(WaitForSingleObject(*mutex, Timex) == WAIT_OBJECT_0){
return 1;
}
return 0;
}
int MUTEX_UNLOCK(MUTEX *mutex){
return ReleaseMutex(*mutex);
}
MUTEX mutex_q = NULL;
MUTEX mutex_p = NULL;
並定義:
# include <process.h>
# define OS_WINDOWS
# define MUTEX HANDLE
# include <Windows.h>
# define EXIT_THREAD() { _endthread(); }
# define START_THREAD(a, b) { _beginthread( a, 0, (void *)( b ) ); }
線程頭文件:
#ifndef __THREAD_H
#define __THREAD_H
class Thread{
public:
Thread ( void );
~Thread ( void );
static void BackgroundCalculator ( void *unused );
};
#endif
好吧,我似乎找不到問題。 調試后,我想通過以下代碼“強制”獲取鎖(從典當抽象機中獲取):
if (strcmp("/routeme", cmdtext, true) == 0){
new fromnode = NearestPlayerNode(playerid);
new start = GetTickCount();
while(CalculatePath(fromnode,14,playerid+100) == 0){
printf("0 %d",fromnode);
}
printf("1 %d",fromnode);
printf("Time: %d",GetTickCount()-start);
return 1;
}
但它不斷進行下去,CalculatePath調用靜態單元格AMX_NATIVE_CALL n_CalculatePath(AMX * amx,cell * params)
這有點令人驚訝。 有人看到錯誤嗎?
如果您需要完整的源代碼,請訪問:
http://gpb.googlecode.com/files/RouteConnector_174alpha.zip
額外信息:PLUGIN_EXPORT bool PLUGIN_CALL僅在啟動時執行加載。
靜態單元格AMX_NATIVE_CALLs僅在從虛擬機調用時執行
ProcessTick()在應用程序的每個進程滴答結束后都會執行,它在完成自己的工作后會在擴展程序中調用它。
到目前為止,我僅在Windows上測試了代碼,但在Linux上確實可以很好地編譯。
編輯:刪除了linux代碼以縮短發布時間。
根據我的見解,您的第一個代碼段僅基於某些條件來解鎖互斥鎖,即在偽代碼中,它就像:
mutex.lock ():
if some_unrelated_thing:
mutex.unlock ()
據我了解您的代碼,原則上,第一個代碼段可以鎖定然后再解鎖。
另一個潛在的問題是您的代碼最終是不安全的異常。 您真的能夠保證鎖定/解鎖操作之間不會發生異常嗎? 因為如果曾經拋出任何未捕獲的異常,您將陷入描述的僵局。 我建議在這里使用某種RAII。
編輯:
未經測試的RAII執行鎖定/解鎖方式:
struct Lock
{
MUTEX& mutex;
bool locked;
Lock (MUTEX& mutex)
: mutex (mutex),
locked (false)
{ }
~Lock ()
{ release (); }
bool acquire (int timeout = -1)
{
if (!locked && WaitForSingleObject (mutex, timeout) == WAIT_OBJECT_0)
locked = true;
return locked;
}
int release ()
{
if (locked)
locked = ReleaseMutex (mutex);
return !locked;
}
};
用法可能是這樣的:
{
Lock q (mutex_q);
if (q.acquire (5)) {
if (!QueueVector.empty ()) {
q.release ();
...
}
}
}
請注意,無論您是否明確地執行此操作,無論~Lock
范圍塊是正常退出還是由於未捕獲的異常,〜Lock都會始終釋放互斥鎖。
我不確定這是否是預期的行為,但是在以下代碼中:
void Thread::BackgroundCalculator( void *unused ){
while( true ){
if(MUTEX_LOCK(&mutex_q, 5) == 1){
if(!QueueVector.empty()){
//cut
MUTEX_UNLOCK(&mutex_q);
//cut
while(MUTEX_LOCK(&mutex_p,90000) != 1){}
//cut
MUTEX_UNLOCK(&mutex_p);
}
}
SLEEP(25);
}
如果QueueVector.empty
為true,則永遠不會解鎖mutex_q
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.