C++11引入线程库,给广大的C++苦逼程序员带来了福音,之前项目中使用的是boost库,为了响应C++11的热情号召,决定最近的项目中就开始使用C++11线程库!
于是我很愉快的写出下面的代码:
但是,编译出错了!不能够啊,boost就是这么写的啊,而且写了好多次了,除了函数名前面的“&”,其他都没有区别啊,不信你看#include <iostream> #include <thread> #include <unistd.h> void haha(int& i) { std::cout << i << std::endl; } int main(int argc, char *argv[]) { int a = 2; std::thread t2(haha, a); sleep(929); return 0; }
这段代码boost运行没有问题啊,什么原因? 自己查看给出的错误提示,我发现原来C++11的线程函数不支持引用传递,自己想想也是啊,线程的生命周期不知道,将自己的变量的引用传递给线程,加入自己把这块内容修改或者删除了,让线程情何以堪,线程运行不是拿到垃圾值,就是崩溃。#include <boost/thread/thread.hpp> #include <boost/shared_ptr.hpp> #include <iostream> void haha(int& i) { std::cout << i << std::endl; } int main(int argc, char* argv[]) { int a = 2; boost::thread thrd(&haha, a); sleep(929); return 0; }
所以,C++的线程函数不支持变量的引用传递(对于这个做法表示支持),并且在编译时期就给出了错误提示。知道了这个原因,第一段代码只需要删除一个引用符号就搞定了!
C++11的问题是解决了,那boost之前的使用岂不是有问题,继续看boost。void haha(int i) { std::cout << i << std::endl; } int main(int argc, char *argv[]) { int a = 2; std::thread t2(haha, a); sleep(929); return 0; }
带着怀疑人生的迷茫心情,写下了下面的代码:
输出222222222222222222222222,全部是2(感觉此时的我就是这个数字啊),没有我想看到的“3”,所以,在线程中执行的对象已经不是之前创建的对象,不是它的引用!换句话说,我写的是引用传递,但是boost自己已经转换成值传递了,哦,,,原来如此,为什么要这个做呢?void haha(int& i) { while(1) { std::cout << i << std::endl; } } int main(int argc, char* argv[]){ int a = 2; boost::thread thrd(&haha, a); sleep(1); a = 3; sleep(929); return 0; }
想起我之前这块的使用都是智能指针的传递,所以我又写了这段测试代码:
不出所料,还是不能编译通过,改成值传递:#include <iostream> #include <thread> #include <unistd.h> class Test { public: Test (int num) : num_(num) {} ~Test(){} void print() { static int i = 0; std::cout << num_ << " " << i++ << std::endl; } private: int num_; }; void fun(std::shared_ptr<Test>& test){ while(1) { std::cout << test.use_count() << std::endl; test->print(); } } void test() { std::shared_ptr<Test> sharePtr(new Test(1)); std::thread t(fun, sharePtr); sleep(929); } int main(int argc, char *argv[]) { test(); return 0; }
编译通过,运行没有问题,查看运行结果,上面智能指针的引用个数为2,一个主线程,一个创建的线程,没问题。#include <iostream> #include <thread> #include <unistd.h> class Test { public: Test (int num) : num_(num) {} ~Test(){} void print() { static int i = 0; std::cout << num_ << " " << i++ << std::endl; } private: int num_; }; void fun(std::shared_ptr<Test> test) { while(1) { std::cout << test.use_count() << std::endl; test->print(); } } void test() { std::shared_ptr<Test> sharePtr(new Test(1)); std::thread t(fun, sharePtr); sleep(929); } int main(int argc, char *argv[]) { test(); return 0; }
那boost呢?写下面代码测试:
这段代码是引用传递,编译成功,运行结果,智能指针的引用个数为2。符合之前的猜想(boost将线程函数的引用传递,默认改成了值传递)。#include <boost/thread/thread.hpp> #include <boost/shared_ptr.hpp> #include <iostream> class Test { public: Test (int num) : num_(num) {} ~Test(){} void print() { static int i = 0; std::cout << num_ << " " << i++ << std::endl; } public: int num_; }; void hello(boost::shared_ptr<Test>& test){ while(1) { std::cout << "thread->" << test.use_count() << std::endl; test->print(); } } void test() { boost::shared_ptr<Test> sharedPtr(new Test(10)); boost::thread thrd(&hello, sharedPtr); sleep(929); } int main(int argc, char* argv[]){ test(); return 0; }
写成值传递:
编译成功,运行成功,运行结果显示,智能指针的引用计数为3,啊?3?怎么回事?什么原因?我只能猜测是boost做了特殊的处理,基于能力有限,只能将问题抛出,请感兴趣的朋友指教和讨论!#include <boost/thread/thread.hpp> #include <boost/shared_ptr.hpp> #include <iostream> class Test { public: Test (int num) : num_(num) {} ~Test(){} void print() { static int i = 0; std::cout << num_ << " " << i++ << std::endl; } public: int num_; }; void hello(boost::shared_ptr<Test> test){ while(1) { std::cout << "thread->" << test.use_count() << std::endl; test->print(); } } void test() { boost::shared_ptr<Test> sharedPtr(new Test(10)); boost::thread thrd(&hello, sharedPtr); sleep(929); } int main(int argc, char* argv[]){ test(); return 0; }