#include
#include
using namespace std;
void Mythread()
{
for (int i = 0; i < 5; i++)
{
cout << "mythread id = " << this_thread::get_id() << endl;
//this_thread::sleep_for(10ms);
this_thread::sleep_for(chrono::seconds(1));
}
cout << "mythread end id = " << this_thread::get_id() << endl;
}
int main()
{
cout << "Main thread id = " << this_thread::get_id() << endl;
thread th(Mythread); //出错
return 0;
}
主线程退出的时候,thread对象被销毁,但是子线程还在运行,所以出错。
int main()
{
cout << "Main thread id = " << this_thread::get_id() << endl;
thread th(Mythread);
th.join();//主线程阻塞,等待子线程退出
cout << "Main thread STOP" << endl;
return 0;
}
在使用thread时。一般需要使用join()等待线程时,不会在创建后立即调用join(),因为这样可能会导致创建线程去等待这个线程执行完成才能继续执行;所以在使用join的时候就需要特别注意使用join的位置和时机。特别创建线程的是主线程的时候,如果子线程需要执行很长时间,那么可能会让主线程处于等待中,那么可能就会导致界面假死的情况(界面编程的时候)。
int main()
{
cout << "Main thread id = " << this_thread::get_id() << endl;
thread th(Mythread); //OK
th.detach();//主线程与子线程分离,守护线程(子线程在后台运行)
cout << "Main thread STOP " << endl;
return 0;
}
detach()的作用是将子线程和主线程的关联分离,分离之后,子线程在后台独立运行,主线程无法拿到子线程的控制权,即使主线程结束子线程也不会结束。
坑:当主线程结束时,不管子线程的逻辑是不是已经执行完,主线程会释放清理与子线程相关的一些变量或者数据资源。因此涉及从其他线程传递到子线程参数或数据的时候,一般使用值传递,而不是用引用和指针。
#include
#include
using namespace std;
bool is_run = false;
void Mythread()
{
for (int i = 0; i < 5; i++)
{
if (!is_run)
break;
cout << "mythread id = " << this_thread::get_id() << endl;
//this_thread::sleep_for(10ms);
this_thread::sleep_for(chrono::seconds(1));
}
cout << "mythread STOP" << endl;
}
int main()
{
cout << "Main thread id = " << this_thread::get_id() << endl;
thread th(Mythread);
is_run = true;//通知子线程退出
th.join();//主线程阻塞,等待子线程退出
cout << "Main thread STOP" << this_thread::get_id() << endl;
return 0;
}
#include
#include
#include
using namespace std;
class Para
{
public:
Para() { cout << "Para create" << endl; }
~Para() { cout << "Para drop" << endl; }
public:
string name;
};
void Mythread(int int_1, string str_2, Para p)
{
cout << "int_1 = " << int_1 <<"\t" << "str_2 = " << str_2 << endl;
cout << "name = " << p.name << endl;
}
int main()
{
Para p;
p.name = "str_test";
thread th(Mythread,100,"string",p); //所有参数做复制
th.join();
return 0;
}
chup三次的原因:创建一次+copy两次;main函数中创建类对象的时候一次,创建线程对象的时候,内部有一个值copy,copy一次,进入线程函数中再copy一次。
参数传递的坑:
void MythreadPtr(Para* p)
{
cout << "MyThreadPtr naem = " << p->name << endl;
}
int main()
{
{
Para p;
p.name = "MyThreadPtr";
thread th(MythreadPtr, &p); //所有参数做复制
th.join();
getchar();
}
return 0;
}
使用指针传递,只是创建、drop了一次。
void MythreadPtr(Para* p)
{
//为了保证主线程比子线程先退出
this_thread::sleep_for(10ms);
cout << "MyThreadPtr naem = " << p->name << endl;
}
int main()
{
{
Para p;
p.name = "MyThreadPtr";
thread th(MythreadPtr, &p); //所有参数做复制
th.detach();
}
getchar();
return 0;
}
发生错误,线程访问的空间p被提前释放,里面的被清理,访问错误。
int main()
{
{
Para p;
p.name = "MyThreadRef";
thread th(MythreadPtr, ref(p)); //ref标识传递为引用
th.detach();
}
getchar();
}
在引用传递的时候,要主动地标识为引用传递ref()。