我目前正在使用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,但遗憾的是没有运气。也许我在我的情况下使用不正确?有人可以给我一些在我的情况下如何使用它们的示例吗?谢谢。
请您参考如下方法:
使用全局变量和手动互斥锁锁定/解锁是解决各种线程问题的坚实基础。例如,在return pOutputCopy;
上,锁定的互斥锁未解锁,这在同一线程再次将其锁定时会导致挂起和 undefined 的行为。至少使用::std::lock_guard
处理互斥锁。