如何维护 C++/STL 中的函数列表?

Posted

技术标签:

【中文标题】如何维护 C++/STL 中的函数列表?【英文标题】:How to maintain a list of functions in C++/STL? 【发布时间】:2009-04-24 14:43:58 【问题描述】:

在直接问你我的问题之前,我要描述一下我的问题的性质。 我正在使用 C++/OpenGL 和 GLFW 库编写 2D 模拟。而且我需要正确管理很多线程。在 GLFW 中,我们必须调用该函数: 线程 = glfwCreateThread(ThreadFunc, NULL); (第一个参数是执行线程的函数,第二个代表这个函数的参数)。 而且glfwCreateThread,每次都必须调用! (即:在每个周期中)。这种工作方式并没有真正帮助我,因为它破坏了我构建代码的方式,因为我需要在主循环范围之外创建线程。所以我正在创建一个 ThreadManager 类,它具有以下原型:

class ThreadManager 

  public:
         ThreadManager();
         void AddThread(void*, void GLFWCALL (*pt2Func)(void*)); 
         void DeleteThread(void GLFWCALL (*pt2Func)(void*));
         void ExecuteAllThreads();

  private:
         vector<void GLFWCALL (*pt2Func)(void*)> list_functions;
         // some attributs             


;

例如,如果我想添加一个特定线程,我只需要使用特定参数和特定函数调用 AddThread。目标只是能够调用: ExecuteAllThreads();在主循环范围内。但为此我需要有类似的东西:

void ExecuteAllThreads() 

      vector<void GLFWCALL (*pt2Func)(void*)>::const_iterator iter_end = list_functions.end();
      for(vector<void GLFWCALL (*pt2Func)(void*)>::const_iterator iter = list_functions.begin();
      iter != iter_end; ++iter) 

           thread = glfwCreateThread(&(iter*), param);
      

在 AddThread 中,我只需将 pt2Func 引用的函数添加到向量:list_functions。

好吧,这就是我想做的事情的总体思路......这是正确的方法吗?你有更好的主意吗?如何做到这一点,真的吗? (我的意思是问题在于语法,我不知道该怎么做)。

谢谢!

【问题讨论】:

【参考方案1】:

您需要在每个模拟周期中创建线程吗?这听起来很可疑。创建一次线程,然后重复使用它们。

线程创建不是一项廉价的操作。您绝对不想在每个迭代步骤中都这样做。

如果可能,我建议您将 Boost.Thread 用于线程,以提供类型安全和其他方便的功能。线程足够复杂,不会抛弃类型安全性并针对原始 C API。

也就是说,您要问的问题是可能的,尽管它会变得混乱。首先,您还需要存储函数的参数,因此您的类看起来像这样:

class ThreadManager 

  public:
         typedef void GLFWCALL (*pt2Func)(void*); // Just a convenience typedef
         typedef std::vector<std::pair<pt2Func, void*> > func_vector;
         ThreadManager();
         void AddThread(void*, pt2Func); 
         void DeleteThread(pt2Func);
         void ExecuteAllThreads();

  private:
         func_vector list_functions;
;

然后执行所有线程:

void ExecuteAllThreads() 

      func_vector::const_iterator iter_end = list_functions.end();

      for(func_vector::const_iterator iter = list_functions.begin();
      iter != iter_end; ++iter) 

           thread = glfwCreateThread(iter->first, iter->second);
      

当然,在 AddThread 中,您必须向向量添加一对函数指针和参数。

请注意,Boost.Thread 可以更简洁地解决大部分问题,因为它希望线程是函子(可以保持状态,因此不需要显式参数)。

你的线程函数可以这样定义:

class MyThread 
  MyThread(/* Pass whatever arguments you want in the constructor, and store them in the object as members */);

  void operator()() 
    // The actual thread function
  

;

而且由于operator()不带任何参数,启动线程就简单多了。

【讨论】:

感谢您的 sn-p !这正是我想要做的......但你是对的:1/我也觉得它很可疑,但它似乎是这样工作的:/ 2/我要去看看 boost 库,我在不熟悉,但由于线程代表了我模拟的关键点,我认为值得学习!【参考方案2】:

尝试使用 boost::function 存储它们怎么样?

它们可以模拟您的特定函数,因为它们的行为类似于真实对象,但实际上是简单的函子。

【讨论】:

+1 对于 boost::function。这是存储具有相同签名的函数指针和/或函数对象的理想方式。这也意味着可以通过 boost::bind 传递额外的参数,并创建函数对象。【参考方案3】:

考虑Boost Thread and Thread Group

【讨论】:

【参考方案4】:

我不熟悉您使用的线程系统。所以请耐心等待。

您不应该维护一个线程标识符列表吗?

 class ThreadManager 
     private:
       vector<thread_id_t> mThreads;
     // ...
 ;

然后在ExecuteAllThreads 你会这样做:

 for_each(mThreads.begin(), mThreads.end(), bind(some_fun, _1));

(使用 Boost Lambda 绑定和占位符参数)其中 some_fun 是您为所有线程调用的函数。

还是您想为给定线程调用一组函数

【讨论】:

我不知道 boost 库的 bind 函数到底是做什么的。维护线程标识符列表的想法很好,但我认为它不能应用于 glfw 系统线程无论如何..会考虑的..谢谢!

以上是关于如何维护 C++/STL 中的函数列表?的主要内容,如果未能解决你的问题,请参考以下文章

STL中的string

swig c++ to perl : 如何使用 c++11 字符串 STL 函数

c++_STL_string类简介

c++_STL_string类简介

C ++ STL列表运算符重载对(根据第一个值排序,使用第二个值访问)

STL之deque使用详解