Skip to main content
 首页 » 编程设计

c++之多线程崩溃

2024年09月03日37wuhuacong

我目前正在使用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处理互斥锁。