gpt4 book ai didi

c++ - Mutex 无法获取锁

转载 作者:行者123 更新时间:2023-11-27 23:25:57 25 4
gpt4 key购买 nike

我有一个问题,我的一个函数无法获取我使用的 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

好吧,我似乎找不到问题所在。调试后我想通过这段代码(来自 pawn 抽象机)“强制”获取锁:

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仅在虚拟机调用时执行

进程记号()在应用程序的每个进程滴答中执行,在它完成自己的工作后,它在扩展中调用这个。

目前我只在 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 总是释放互斥锁,无论您是否明确地这样做,无论范围 block 是正常退出还是由于未捕获的异常而退出。

关于c++ - Mutex 无法获取锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9523532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com