关于 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 能否是一个私有函数呢
试了一下,会发现,答案是可以的