我有一个类ChunkManager
,它有一些(应该是)异步方法。这些方法处理我的游戏引擎中的任务,例如在不同的线程上加载地图块(类似于Minecraft),以便不完全停止主线程(它们是冗长的操作)
以下是其中一种方法:
void ChunkManager::asyncRenderChunks(){
boost::thread loadingThread(&ChunkManager::renderChunks,this);
}
renderChunks的样子:
void ChunkManager::renderChunks(){
activeChunksMutex->lock();
for(int z=0; z < CHUNK_MAX; z=z+1)
{
for(int y=0; y < CHUNK_MAX; y=y+1)
{
for(int x=0; x < CHUNK_MAX; x=x+1)
{
activeChunks[x][y][z]->Render(scnMgr);
}
}
}
activeChunksMutex->unlock();
}
这应该有用,对吗?然而,当它运行时它会崩溃。我有一种感觉,它与我在线程创建后对线程的处理有关,因为如果我放了
loadingThread.join();
在前面提到的方法中,它工作正常,但主线程停止了,因为很明显它只是等待新线程完成,有效地让我回到原点。 有什么建议? 对不起,如果这是一个迟钝的问题,我是线程概念的新手。 感谢。
更新(2013年4月9日): 我找到了这个宝石:http://threadpool.sourceforge.net/ ..并解决了我的问题!
答案 0 :(得分:0)
如果您可以加入该主题,那么它必须是可加入的。
正如in the documentation所述:
当代表执行线程的
boost::thread
对象被销毁时,如果线程可加入,程序将终止。
您创建了一个本地thread
对象,立即让它超出范围:ChunkManager::asyncRenderChunks
返回时它被销毁。
或者:
使其成为分离(不可连接)的线程
void ChunkManager::asyncRenderChunks() {
boost::thread loadingThread(&ChunkManager::renderChunks,this);
loadingThread.detach();
}
或在其他地方创建thread
对象并保持活着
class ChunkManager {
boost::thread renderingThread;
bool renderChunkWork; // work to do flag
Chunk activeChunks[CHUNK_MAX][CHUNK_MAX][CHUNK_MAX];
boost::mutex activeChunksMutex;
boost::condition_variable activeChunksCV;
bool shutdown; // shutdown flag
void renderChunks() {
for(int z=0; z < CHUNK_MAX; ++z)
for(int y=0; y < CHUNK_MAX; ++y)
for(int x=0; x < CHUNK_MAX; ++x)
activeChunks[x][y][z]->Render(scnMgr);
}
void renderChunkThread() {
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
while (true) {
while (!(renderChunkWork || shutdown))
activeChunksCV.wait(guard);
if (shutdown)
break;
renderChunks();
doRenderChunks = false;
}
}
public:
ChunkManager()
: loadingThread(&ChunkManager::renderChunkThread, this),
renderChunkWork(false), shutdown(false)
{}
~ChunkManager() {
{ // tell the rendering thread to quit
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
renderChunkShutdown = true;
activeChunksCV.notify_one();
}
renderingThread.join()
}
void asyncRenderChunks() {
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
if (!renderChunkWork) {
renderChunkWork = true;
activeChunksCV.notify_one();
}
}
};
NB。一般来说,即时创建线程并不比预先创建线程好,只是在有事情要做时唤醒它们。它避免了在最后一个调用完成之前如何处理对asyncRenderChunks
的第二次调用(启动第二个线程?块?),并移动与线程创建相关的延迟。
在这段代码中意识到这一点非常重要:
void ChunkManager::asyncRenderChunks() {
SomeType myObject;
}
将创建实例myObject
,然后立即销毁。
答案 1 :(得分:0)
崩溃,因为在当前版本的Boost.Thread
中,您必须加入()一个主题或detach()
- 否则~thread
would terminate the program。 (在早期版本中~thread
用于自动调用detach()
。)
因此,如果您不想加入该主题 - 只需将其分开:
boost::thread loadingThread(&ChunkManager::renderChunks,this);
loadingThread.detach();