【问题标题】:SDL_AddTimer in which way it is used to avoid multithreading problemsSDL_AddTimer 用于避免多线程问题的方式
【发布时间】:2014-05-27 07:04:31
【问题描述】:

Wiki Link for SDL_AddTimer

SDL_AddTimer 的 wiki 文档声称

"请注意,可以通过将要执行的函数的地址和 userevent.data2 的参数提供给 userevent.data1 来避免 SDL 计时器的多线程问题,然后在事件循环。”

如何使用它来避免多线程问题? 有人能解释一下我无法理解的陈述吗?

【问题讨论】:

    标签: multithreading sdl sdl-2


    【解决方案1】:

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

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

    这将引入 my_function() 的并发问题。

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

    【讨论】:

      【解决方案2】:

      我也阅读了该 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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多