C++高级——bind和function联动实现微线程池
bind
昨天有粉丝问我,bind1st和bind有啥区别?今天就来简单讲讲。
bind1st和bind2nd在STL中主要用于二元函数对象,将其中的一元绑定成一个固定的量,成为一元函数变量。
在C++11标准中,这两位因为不够灵活,所以已经被bind所取代。
bind起源于非标准boost库,在c++11标准中正式纳入标准库,其更加灵活,最多可以绑定20个函数对象的参数。
bind的用法
先随便整上点函数:
void hello(string str) {
cout << str << endl; }
int sum(int a, int b) {
return a + b; }
class Test
{
public:
int sum(int a, int b) {
return a + b; }
};
然后再来看bind的实际应用:
int main()
{
// bind是函数模板 可以自动推演模板类型参数
bind(hello, "hello bind!")()//result:print:hello bind!
cout << bind(sum, 10, 20)() << endl;//result:print:30
cout << bind(&Test::sum, Test(), 20, 30)() << endl;//result:print:50
// 参数占位符 绑定器出了语句,无法继续使用
bind(hello, _1)("hello bind 2!");
cout << bind(sum, _1, _2)(200, 300) << endl;//result:print:500
return 0;
}
在语句bind(hello, "hello bind!")();
中,bind将“hello bind!”绑定至hello的string类型参数,并返回一个函数对象,调用这个函数对象的operator()函数,完成打印字符串的过程。
在语句bind(hello, _1)("hello bind 2!");
中的_1是名称空间 placeholders中的,用法placeholder::_1
。
此为参数占位符,代表hello的第一个参数等待用户输入。在本例中将参数“hello bind 2!”传递给operator()函数完成调用。
用function实现对bind绑定的函数对象的类型保留
bind有个缺点,不知道大家发现了没有。
bind无法保存它所绑定过的函数对象!
所以就需要function和它进行配合。
int main()
{
function<void(string)> func1 = bind(hello, _1);
func1("hello china!");
func1("hello shan xi!");
func1("hello si chuan!");
return 0;
}
bind 和function实现线程池(假)
先把线程类定义好:
// 线程类
class Thread
{
public:
Thread(function<void(int)> func, int no) :_func(func), _no(no) {
}
//这里需要包含头文件#include<thread>
thread start()
{
//定义线程t执行func函数
thread t(_func, _no); // _func(_no)
return t;
}
private:
function<void(int)> _func;//接收绑定器返回的函数对象
int _no;//线程编号
};
再定义好线程池类:
// 线程池类
class ThreadPool
{
public:
ThreadPool() {
}
~ThreadPool()
{
// 这里是指针,所以不能依靠vector析构自动析构,得手动释放Thread对象占用的堆资源
for (int i = 0; i < _pool.size(); ++i)
{
delete _pool[i];
}
}
// 开启线程池
void startPool(int size)
{
for (int i = 0; i < size; ++i)
{
_pool.push_back(
new Thread(bind(&ThreadPool::runInThread, this, _1), i));
}
//执行线程函数
for (int i = 0; i < size; ++i)
{
_handler.push_back(_pool[i]->start());
}
for (thread &t : _handler)
{
//等待线程执行完毕
t.join();
}
}
private:
vector<Thread*> _pool;
vector<thread> _handler;
// 把runInThread这个成员方法充当线程函数 thread pthread_create
void runInThread(int id)
{
cout << "call runInThread! id:" << id << endl;
}
};
应用:
int main()
{
ThreadPool pool;
pool.startPool(10);//创建10个线程
return 0;
}
#endif
这里只是个概念模型,用还是用不了的。
参考文献
[1] 施磊.腾讯课堂——C++高级.图论科技,2020.7.