【问题标题】:Crashes with multithreading多线程崩溃
【发布时间】: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_lockstd::condition_variable 的组合。

标签: c++ multithreading timer crash sdl-2


【解决方案1】:

使用全局变量和手动互斥锁/解锁是解决各种线程问题的坚实基础。例如,return pOutputCopy; 锁定的互斥锁未解锁,这会导致挂起和当它再次被同一线程锁定时导致未定义的行为。至少使用::std::lock_guard来处理互斥锁。

【讨论】:

    猜你喜欢
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 2012-02-26
    相关资源
    最近更新 更多