关于 c++11 的线程库,我们有如下几个问题:
- 可否不传参数
- 可否传递多个参数
- 可否传递 const 参数
- 可否传递引用参数
- 可否传递 const 引用参数
- std::thread 结构可否放入容器
- std::thread 可否在类内部使用
针对以上问题,我们先来看一个标准的 c++11 线程库要怎么使用:
#include <stdio.h> #include <thread> void f(int a) { printf("%d\n", a); } int main() { printf("hello world\n"); std::thread t(f, 1); t.join(); return 0; }
>g++ test_thread.cpp -std=c++11 -pthread && ./a.out hello world 1
然后试了一下不传参数,是可以的;多个参数,也是可以的;const 参数也是可以的
当试到传引用的时候,需要这么写才可以
#include <stdio.h> #include <thread> #include <string> void f(int a, std::string& b) { printf("%d\n%s\n", a, b.c_str()); b = "456"; } int main() { printf("hello world\n"); std::string str = "123"; std::thread t(f, 1, std::ref(str)); t.join(); printf("%s\n", str.c_str()); return 0; }
>g++ test_thread.cpp -std=c++11 -pthread && ./a.out hello world 1 123 456
然后 const 引用也是可以的
容器中也可以放,但是取出的时候只能取出引用,而不能取出值
#include <stdio.h> #include <thread> #include <string> #include <vector> void f(int a, const std::string& b) { printf("%d\n%s\n", a, b.c_str()); } int main() { printf("hello world\n"); std::string str = "123"; std::vector<std::thread> vecT; vecT.push_back(std::thread(f, 1, std::ref(str))); std::thread& t = vecT[0]; t.join(); printf("%s\n", str.c_str()); return 0; }
>g++ test_thread.cpp -std=c++11 -pthread && ./a.out hello world 1 123 123
最后,在类中使用的话,像这么写的话
#include <stdio.h> #include <thread> #include <string> #include <vector> class TestClass { public: void f(int a, const std::string& b) { printf("%d\n%s\n", a, b.c_str()); } void r() { printf("hello world\n"); std::string str = "123"; std::vector<std::thread> vecT; vecT.push_back(std::thread(f, 1, std::ref(str))); std::thread& t = vecT[0]; t.join(); printf("%s\n", str.c_str()); } }; int main() { TestClass testClass; testClass.r(); return 0; }
是会报错的
>g++ test_thread.cpp -std=c++11 -pthread && ./a.out test_thread.cpp: In member function ‘void TestClass::r()’: test_thread.cpp:16:55: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, int, std::reference_wrapper<std::basic_string<char> >)’ vecT.push_back(std::thread(f, 1, std::ref(str))); ^ test_thread.cpp:16:55: note: candidates are: In file included from test_thread.cpp:2:0: /usr/local/include/c++/4.8.2/thread:133:7: note: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (TestClass::*)(int, const std::basic_string<char>&); _Args = {int, std::reference_wrapper<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >}] thread(_Callable&& __f, _Args&&... __args) ^ /usr/local/include/c++/4.8.2/thread:133:7: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘void (TestClass::*&&)(int, const std::basic_string<char>&)’ /usr/local/include/c++/4.8.2/thread:128:5: note: std::thread::thread(std::thread&&) thread(thread&& __t) noexcept ^ /usr/local/include/c++/4.8.2/thread:128:5: note: candidate expects 1 argument, 3 provided /usr/local/include/c++/4.8.2/thread:122:5: note: std::thread::thread() thread() noexcept = default; ^ /usr/local/include/c++/4.8.2/thread:122:5: note: candidate expects 0 arguments, 3 provided
搜了一下,看到 stackoverflow 上有人说, https://stackoverflow.com/ques…
The problem is that a member function can’t be called without an object. Provide a pointer to this so that the current object is used:
thread t(&ThreadClass::myThread, this, 10);
You could use an instance of any ThreadClass object, but in your case, it seems this is the right thing to do.NOTE: Remember you need a reference to the created thread so that you can do a join() later on.
所以其实是类的成员函数中,隐含了第一个参数是一个 this 指针的原因
#include <stdio.h> #include <thread> #include <string> #include <vector> class TestClass { public: void f(int a, const std::string& b) { printf("%d\n%s\n", a, b.c_str()); } void r() { printf("hello world\n"); std::string str = "123"; std::vector<std::thread> vecT; vecT.push_back(std::thread(&TestClass::f, this, 1, std::ref(str))); std::thread& t = vecT[0]; t.join(); printf("%s\n", str.c_str()); } }; int main() { TestClass testClass; testClass.r(); return 0; }
改写成这样,就可以了
>g++ test_thread.cpp -std=c++11 -pthread && ./a.out hello world 1 123 123
那很自然的,会接着一个问题,就是这个 f 能否是一个私有函数呢
试了一下,会发现,答案是可以的