#include "MsgThread.h"
#include
using namespace std;
static mutex gs_mutex;
static bool flag = false;
bool MsgThread::MainLoop(void *p)
{
auto pThis = static_cast(p);
while (true)
{
if (gs_mutex.try_lock())
{
if (pThis->m_EventVec.size() != 0)
{
auto pObj = *(pThis->m_EventVec.begin());
dealMsg(pObj);
pThis->m_EventVec.erase(pThis->m_EventVec.begin());
}
gs_mutex.unlock();
}
}
return true;
}
MsgThread::MsgThread()
{
m_pThread = new thread(&MsgThread::MainLoop, this,this);
m_pThread->detach();
}
MsgThread* MsgThread::getInstance()
{
if (m_DataThread == NULL)
{
auto pDataThread = new MsgThread();
m_DataThread = pDataThread;
}
return m_DataThread;
}
void MsgThread::dealMsg(Message& _msg)
{
if (_msg._Selector == NULL)
{
_msg.pLayer->HandleMessage(_msg.pLayer, _msg.ret);
return;
}
bool ret = (_msg.pLayer->*_msg._Selector)(_msg.pLayer);
if (ret)
{
_msg.pLayer->HandleMessage(_msg.pLayer,_msg.ret);
}
else
{
_msg.pLayer->HandleMessage(_msg.pLayer,0);
}
}
void MsgThread::sendMsg(Message _msg)
{
gs_mutex.lock();
m_EventVec.push_back(_msg);
CCLOG("vec.size:%d",m_EventVec.size());
flag = true;
gs_mutex.unlock();
}
MsgThread* MsgThread::m_DataThread = NULL;
```
我在MsgThread中实现了C++11的多线程,在mainloop 和sendmsg中加锁,但是好像死锁了,不知道要怎么搞请大神帮忙,
mainloop中的while循环主要处理sendmsg函数添加的消息,我在UI线程里连续调用sendmsg函数5次,但是在mainloop中
只处理了一次,而且sendmsg函数打印m_EventVec的size也只有一个,求高人指点
没人帮我,昨天搞了一晚上,找到个原因,在mainloop中我调用CCLog函数,以下是cclog的源代码
static void _log(const char *format, va_list args)
{
char buf;
vsnprintf(buf, MAX_LOG_LENGTH-3, format, args);
strcat(buf, "\n");
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
__android_log_print(ANDROID_LOG_DEBUG, "cocos2d-x debug info", "%s", buf);
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_WP8
WCHAR wszBuf = {0};
MultiByteToWideChar(CP_UTF8, 0, buf, -1, wszBuf, sizeof(wszBuf));
OutputDebugStringW(wszBuf);
WideCharToMultiByte(CP_ACP, 0, wszBuf, -1, buf, sizeof(buf), nullptr, FALSE);
printf("%s", buf);
SendLogToWindow(buf);
fflush(stdout);
#else
// Linux, Mac, iOS, etc
fprintf(stdout, "%s", buf);
fflush(stdout);
#endif
Director::getInstance()->getConsole()->log(buf);
}
```
在cclog的源代码中会调用SendLogToWindow(buf)这个函数,一下是该函数源代码
void SendLogToWindow(const char *log)
{
// Send data as a message
COPYDATASTRUCT myCDS;
myCDS.dwData = CCLOG_STRING_TAG;
myCDS.cbData = (DWORD)strlen(log) + 1;
myCDS.lpData = (PVOID)log;
if (Director::getInstance()->getOpenGLView())
{
HWND hwnd = Director::getInstance()->getOpenGLView()->getWin32Window();
SendMessage(hwnd,
WM_COPYDATA,
(WPARAM)(HWND)hwnd,
(LPARAM)(LPVOID)&myCDS);
}
}
```
在win32环境下,该函数会调用SendMessage函数,而这个函数是个阻塞函数,意味着
发送消息后,要等待主线程处理该消息,那么问题就来了,当我在mainloop中加上锁,该函数就会一直阻塞,
导致整个UI卡死,不加锁却不会阻塞,这里是我新的疑问,不明白sendmessage在加锁后为什么会阻塞,
而且这个问题也不固定,有时候会阻塞,有时候却不会阻塞,没辙了我把SendMessage改成postMessage了,


你用的哪个版本的cocos2dx引擎,我的是cocos2d-x-3.3rc0.
void _log函数中并没有调用SendLogToWindow函数,引擎中根本没有SendLogToWindow这个函数。
你可能用的是老版本的引擎,或者SendLogToWindow这个函数是你自己加进去的。
下面是cocos2d-x-3.3rc0版中的_log函数源码:
static void _log(const char *format, va_list args)
{
char buf;
vsnprintf(buf, MAX_LOG_LENGTH-3, format, args);
strcat(buf, "\n");
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
__android_log_print(ANDROID_LOG_DEBUG, “cocos2d-x debug info”, “%s”, buf);
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_WP8
WCHAR wszBuf = {0};
MultiByteToWideChar(CP_UTF8, 0, buf, -1, wszBuf, sizeof(wszBuf));
OutputDebugStringW(wszBuf);
WideCharToMultiByte(CP_ACP, 0, wszBuf, -1, buf, sizeof(buf), nullptr, FALSE);
printf("%s", buf);
fflush(stdout);
#else
// Linux, Mac, iOS, etc
fprintf(stdout, “cocos2d: %s”, buf);
fflush(stdout);
#endif
Director::getInstance()->getConsole()->log(buf);
}
函数里已经有了OutputDebugStringW,
再调用SendLogToWindow发送到窗口显示没有必要。
cocos2d-x-3.4
我也觉得没有用,但是我不确定引擎这样写的用意,所以没有去掉
你上锁, 一搬只在公用数据的 存/储 处理上锁和解锁
比如:
push 入列表时候:
lock
push 入列表
unlock
锁的东西尽量短小,事件和其他处理 只用在解锁后 调用
你上面的代码, 不用把log代码写在锁里面,可以在解锁后