需要一些有关此代码的帮助。我创建了一个函数来在我的应用程序中打印一些调试文本(“debug”函数)。 2个线程(FD_READ和incDataProcess)正在使用此函数在调试窗口中打印一些信息。当我运行以下代码时,数据显示不好,可能是因为2线程正在快速访问该函数(数据竞争)。当我尝试使用互斥锁一次限制对1个线程的函数的访问时,程序挂起。当我用互斥锁保护函数时,我不明白为什么程序会挂起。我的互斥锁我做错了什么?
static mutex printMutex;
static mutex readQueueMutex;
//....
void debug(LPSTR text1, LPSTR text2, LPSTR text3)
{
// printMutex.lock(); // the combination of lock - unlock
// makes the program hang (solution 1)
// lock_guard<mutex>_(printMutex); // Solution 2, the program
// hangs also
char *Text1 = text1;
char *Text2 = text2;
char *Text3 = text3;
char Text[2048];
strcpy_s(Text, Text1);
strcat_s(Text, Text2);
strcat_s(Text, Text3);
int TextLen = SendMessage(hDebug, WM_GETTEXTLENGTH, 0, 0);
SendMessage(hDebug, EM_SETSEL, (WPARAM)TextLen, (LPARAM)TextLen);
SendMessage(hDebug, EM_REPLACESEL, FALSE, (LPARAM)Text);
// printMutex.unlock(); // See comment solution 1
}
//.....
void incDataProcess(void *pBuffer)
{
debug("incDataThread launched\n", "", "");
for(;;)
{
while (!readQueue.empty())
{
readQueueMutex.lock();
string sReadBuffer = readQueue.front();
readQueue.pop();
readQueueMutex.unlock();
string var;
char *pVar = nullptr;
char *next_token = nullptr;
istringstream iss(sReadBuffer); // Put into a stream
while (getline(iss, var)) // Default delimiter '\n'
{
pVar = _strdup(var.c_str()); // Cast string to char *
if( strstr(pVar, "Qh57=") != NULL)
{
char *label = strtok_s(pVar, "=", &next_token);
char *pFoFd = strtok_s(NULL, "\n", &next_token);
strcpy_s(foFd, pFoFd);
debug("Qh57=", foFd, "\n");
}
} //while getline
} // while queue is not empty
} // infinite for loop
}
//.....
case FD_READ:
{
debug("FD_READ event\n", "", "");
int bytes_recv = recv(Socket, readBuffer, sizeof(readBuffer), 0);
readQueueMutex.lock();
readQueue.push(readBuffer);
readQueueMutex.unlock();
char bytes[256];
_itoa_s(bytes_recv, bytes, 10);
debug("Received ", bytes, " bytes from server\n")
debug("End of FD_READ\n", "", "");
}
break;
这是调试窗口,没有同步:
FD_READ event
Received 8 bytes from server
End of FD_READ
Qh57=0
FD_READ eventReceived 49 bytes from serverEnd of FD_READ // Display problem
// when second
// thread calls the function
FD_READ event
Received 127 bytes from server
End of FD_READ
FD_READ event
Received 57 bytes from server
End of FD_READ
Qh57=1
答案 0 :(得分:1)
SendMessage阻塞,直到窗口处理消息。如果该窗口是在另一个也调用debug的线程上创建的,那么就会出现死锁。
答案 1 :(得分:1)
Brandon Kohn's answer是你陷入僵局的原因。至于解决方案,我建议您执行以下操作:
static std::queue<std::string> pendingDebugMessages;
void debug(LPSTR text1, LPSTR text2, LPSTR text3)
{
lock_guard<mutex>_(printMutex);
pendingDebugMessages.push(std::string());
std::string& finalString = pendingDebugMessages.back();
finalString = text1;
finalString += text2;
finalString += text3;
}
// Call this regularly from your message pump thread
void PrintPendingMessages()
{
lock_guard<mutex>_(printMutex);
while(!pendingDebugMessages.empty())
{
int TextLen = SendMessage(hDebug, WM_GETTEXTLENGTH, 0, 0);
SendMessage(hDebug, EM_SETSEL, (WPARAM)TextLen, (LPARAM)TextLen);
SendMessage(hDebug, EM_REPLACESEL, FALSE, (LPARAM)pendingDebugMessages.front().c_str());
pendingDebugMessages.pop();
}
}