我有一个问题,我的一个函数不能对我使用的两个互斥锁中的一个进行锁定。我在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;
}init:
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代码以缩短post。
发布于 2012-03-04 17:47:21
根据我所看到的,您的第一个代码段只在某些条件下解锁互斥锁,例如,在伪代码中,它类似于:
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总是以这种方式释放互斥对象,无论您是否显式地这样做,作用域块是否正常退出,还是由于一个不明确的异常。
发布于 2012-03-04 17:50:50
我不确定这是否是有意的行为,但在下面的代码中:
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为真,则永远不会解锁mutex_q。
https://stackoverflow.com/questions/9523532
复制相似问题