SDL_AddTimer,它被用来避免多线程问题



SDL_AddTimer的Wiki链接

SDL_AddTimer的wiki文档声称

"注意,可以通过给userevent来避免SDL计时器的多线程问题。要执行的函数的地址和userevent。Data2的参数,然后在事件循环中处理它。"

如何避免多线程问题?谁能解释一下,我听不懂是怎么回事?

第一个例子假设工作函数,即你想要执行的函数(my_function())驻留在my_callbackfunc()函数中。

SDL_AddTimer()指定:使用这个函数设置一个回调函数,在指定的毫秒数过去后在单独的线程上运行。

这会给my_function()带来并发性问题。

解决方案(第二个例子),假设事件轮询线程是添加计时器的线程,并调用该线程中的函数。

我也读过那个SDL文档,它对它的"解决方法"提出了一个真的糟糕的建议。具体来说,它建议将函数地址强制转换为void指针。这是不便携的!不要这样做,请阅读

https://isocpp.org/wiki/faq/pointers-to-members cant-cvt-fnptr-to-voidptr

如果你觉得你必须这样做(或类似的事情),那么我建议将函数指针包装在结构/类中。

struct Wrapper
{
 void (*f)(void*);
 Wrapper(void (*F)(void*)) { f = F; }
};

当您想要推送自定义事件时创建包装器

SDL_Event event;
event.user.data1 = (void*) new Wrapper(your_function);
event.user.data2 = your_function_arg;
SDL_PushEvent(&user);

然后在主循环中,执行调用,删除包装器

SDL_WaitEvent(&event);
if (event.type == SDL_USEREVENT)
{
 Wrapper *p = ((Wrapper*) event.user.data1)
 p->f(event.user.data2);
 delete p;
}

最新更新