c++ - 多线程崩溃

标签 c++ multithreading timer crash sdl-2

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

关于c++ - 多线程崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43568556/

相关文章:

c# - 使用MemoryBarrier传播Dictionary <int,T>多线程应用程序中的更改

java - 如何在 Java 多线程消费者-生产者场景中了解应用程序是否已完成计算

php - 为什么 PHP 中禁用 pcntl_fork() ?

java - 每天在特定时间之间每 15 分钟运行一次方法

javascript - 使用 JQuery Ajax 自动登录?

c++ - 存储/广播指向函数<void()的函数指针

c++ - 如何使用 C++ 计算 Hailstone 序列中的奇数个数

c++ - 为什么 void{} 不存在?

c++ - 如何在 C++11 的 Mac OS X 上命名 std::thread?

java.util.Timer 与 EJB TimerBean