如何维护 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 中的函数列表?的主要内容,如果未能解决你的问题,请参考以下文章
swig c++ to perl : 如何使用 c++11 字符串 STL 函数