【发布时间】:2017-04-23 07:32:46
【问题描述】:
我目前正在使用 SDL2 制作游戏,并且开始使用计时器,并且我将回调设置为调用 SDL_CreateTextureFromSurface 的函数。然后我在网上看到SDL_CreateTextureFromSurface只能从主线程调用,所以我设置了一个队列系统,其中定时器线程可以将它的请求添加到调用SDL_CreateTextureFromSurface的队列中,并且主线程通过队列并实际调用它.当我尝试为计时器线程和主线程上的队列添加函数创建互斥体时,我的问题现在发生了,通过队列并处理条目。
我为 SDL_CreateTextureFromSurface 制作了一个包装器,以将条目添加到队列中。
multithread_protection.cpp(从定时器线程调用的函数):
#include "multithread_protection.h"
#include <SDL.h>
#include <mutex>
std::mutex mutex;
bool bQueueCurrentlyProcessing = false;
std::vector<function_t> queue;
SDL_Texture * SDLCALL Queue_SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
{
mutex.lock();
function_t func;
func.renderer = renderer;
func.surface = surface;
func.pOutput = 0;
if (queue.size() == 0)
{
func.id = 0;
}
else if (queue.size() > 0)
{
func.id = queue[queue.size() - 1].id + 1;
}
queue.push_back(func);
mutex.unlock();
while (true)
{
mutex.lock();
for (int i = 0; i < queue.size(); i++)
{
if (queue[i].id == func.id)
{
// This entry is validated as the one that we put in.
if (queue[i].pOutput)
{
SDL_Texture *pOutputCopy = queue[i].pOutput;
////bQueueCurrentlyProcessing = true;
////queue[i].acknowledged_completed = true;
//if (!pOutputCopy)
//{
// int a;
// a = 5;
//}
return pOutputCopy;
return 0;
}
i = 0;
}
}
mutex.unlock();
}
}
multithread_protection.h:
struct function_t
{
SDL_Renderer * renderer;
SDL_Surface * surface;
unsigned int id;
SDL_Texture *pOutput;
bool acknowledged_completed = false;
};
extern bool bQueueCurrentlyProcessing;
extern std::vector<function_t> queue;
extern std::mutex mutex;
SDL_Texture * SDLCALL Queue_SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface);
render.cpp(主线程):
void HandleMultithreadedFunctionQueue()
{
mutex.lock();
//bQueueCurrentlyProcessing = true;
for (int i = 0; i < queue.size(); i++)
{
if (queue[i].pOutput == 0) // This entry hasn't been processed yet.
{
queue[i].pOutput = SDL_CreateTextureFromSurface(queue[i].renderer, queue[i].surface);
}
if (queue[i].acknowledged_completed)
{
//queue.erase(queue.begin() + i); // Erase entry from queue since it finished, and we don't need it anymore.
}
}
//bQueueCurrentlyProcessing = false;
mutex.unlock();
}
互斥体不断使程序崩溃,有时会导致奇怪的阻塞。如果有人可以告诉我如何更好地处理这种多线程情况,那就太好了。谢谢!
编辑: 我尝试使用 std::lock_guard、std::unique_lock 和 std::condition_variable,但遗憾的是没有运气。也许我在我的情况下错误地使用它们?有人可以给我一些如何在我的情况下使用它们的例子吗?谢谢。
【问题讨论】:
-
使用
std::lock_guard进行 RAII 样式的锁定和解锁。 -
避免像瘟疫一样手动锁定和解锁。您可能需要
std::unique_lock和std::condition_variable的组合。
标签: c++ multithreading timer crash sdl-2