C++11中与多线程相关的头文件:
一个线程只能被join或detach一次。一旦被detach就不能被join,幸运的是可以在join之前加joinable函数来判断
#include
#include
using namespace std;
void function_1()
{
cout << "Beauty is only skin-deep" << endl;
}
int main() //main函数为主线程
{
thread t1 (function_1);
//t1.join(); //主线程等待线程t1结束
t1.detach(); //t1将会在后台独立运行,即为守护进程(daemon process)
if (t1.joinable()) //线程一旦detach就不能被join,幸运的是,可以用joinable函数判断防止程序崩溃
t1.join();
cout << "run remaining main thread" << endl;
return 0;
}
在创建t1线程后,主线程main函数肯定是要执行另外的操作以便从创建新线程中获益。然而一旦 main函数中在线程t1被join之前抛出异常,线程t1将被销毁。此时就需要对main函数中的代码使用异常处理来保护新创建的线程t1.
#include
#include
using namespace std;
void function_1()
{
cout << "Beauty is only skin-deep" << endl;
}
int main()
{
std::thread t1(function_1);
try { //若主线程不加异常处理,那么在for循环抛出异常后线程t1将会在被join之前被销毁
for (int i = 0; i < 100; ++i)
cout << "from main" << i << endl;
}
catch (...) {
t1.join();
throw;
}
t1.join();
}
int main()
{
string s = "where there is no trust,ther is no love";
cout <<"main.id: "<< this_thread::get_id() <<endl;
thread t1((Fctor()), move(s));
cout <<"t1.id: "<< t1.get_id() << endl;
t1.join();
return 0;
}
显示系统可同时运行的最大线程数:thread::hardware_concurrency().
在C++的应用程序中,都有一个默认的主线程:main函数。在C++11中,可以通过创建std:thread类的对象来创建其他的线程,每个std::thread类的对象都可以与一个线程相关联。可以使用std::thread 对象附加一个回调(Callback),当这个新线程启动时,回调将被执行,回调可以为: 函数指针,函数对象,lambda函数。
新线程在创建之后立即开始启动。
#include
#include
using namespace std;
void function_1()
{
cout << "Beauty is only skin-deep" << endl;
}
int main() //main函数为主线程
{
thread t1 (function_1); //使用函数指针创建线程
//t1.join(); //主线程等待线程t1结束
t1.detach(); //t1将会在后台独立运行,即为守护进程(daemon process)
if (t1.joinable()) //线程一旦detach就不能被join,幸运的是,可以用joinable函数判断防止程序崩溃
t1.join();
cout << "run remaining main thread" << endl;
return 0;
}
① 仿函数创建线程:
std::thread t1(Fctor()); // 这种表述会让编译器认为创建一个返回值为thread名为t1的函数,函数参数为指向一个函数的指针(该函数返回值为Fctor类,无参数)
class Fctor
{
public:
void operator()()
{
for (int i = 0; i > -100; i--)
cout << "from t1: " <<i<< endl;
}
};
int main()
{
//std::thread t1(Fctor()); // 这种表述会让编译器认为创建一个返回值为thread名为的函数,函数参数为指向一个函数的指针(该函数返回值为Fctor类,无参数)
std::thread t1((Fctor())); //利用仿函数创建线程
for (int i = 0; i < 5; i++)
std::cout << "run middle main thread" << std::endl;
try {
for (int i = 0; i < 100; ++i)
cout << "from main: " <<i<< endl;
}
catch (...) {
t1.join();
throw;
}
t1.join(0);
return 0;
}
② 创建类对象绑定线程对象创建线程
int main()
{
Fctor fct; //方法②:创建Fctor线程对象fct并绑定线程t1
std::thread t1(fct);
for (int i = 0; i < 5; i++)
std::cout << "run middle main thread" << std::endl;
try {
for (int i = 0; i < 100; ++i)
cout << "from main: " <<i<< endl;
}
catch (...) {
t1.join();
throw;
}
t1.join(0);
return 0;
}
thread t([](int x){ return x*x; }, 6);
线程默认只能进行值传递,即将参数复制到线程的内存空间,而无法进行引用传递
#include
#include
#include
using namespace std;
class Fctor
{
public:
void operator()(string msg)
{
cout << "t1 says: " << msg << endl;
msg = "Trust is the mother of deceit.";
}
};
int main()
{
string s = "Where there is no trust,there is no love";
thread t1((Fctor()), s);
t1.join();
cout << "from main: " << s << endl;
return 0;
}
#include
#include
#include
using namespace std;
class Fctor
{
public:
void operator()(string& msg)
{
cout << "t1 says: " << msg << endl;
msg = "Trust is the mother of deceit.";
}
};
int main()
{
string s = "Where there is no trust,there is no love";
thread t1((Fctor()), s);
t1.join();
cout << "from main: " << s << endl;
return 0;
}
输出:
对线程实现引用传递的方式:
使用 std::ref 显式地声明传入线程的参数为原参数的引用,共享一段内存空间
class Fctor
{
public:
void operator()(string& msg)
{
cout << "t1 says: " << msg << endl;
msg = "Trust is the mother of deceit.";
}
};
int main()
{
string s = "Where there is no trust,there is no love";
thread t1((Fctor()), ref(s));
t1.join();
cout << "from main: " << s << endl;
return 0;
}
将参数从主线程移动到新建线程以及线程之间的移动:std::move
#include
#include
#include
using namespace std;
class Fctor
{
public:
void operator()(string& msg)
{
cout << "t1 says: " << msg << endl;
msg = "Trust is the mother of deceit.";
}
};
int main()
{
string s = "Where there is no trust,there is no love";
thread t1((Fctor()), move(s)); //使用move将主线程参数移动到线程t1,此时主线程main函数的s变为空
thread t2 = move(t1); //使用move将线程t1移动到另一个新建线程t2,线程t1变为空
t2.join();
cout << "from main: " << s << endl;
return 0;