#include <iostream>
#include<thread>
#include<string>
using namespace std;
//线程id:每个线程都有一串唯一的数字来标识,这串数字就是线程id。可通过std::this_thread::get_id()来获取。
//detach时
//1.如果传递int这种简单类型参数,建议都是值传递,不要用引用(可能会发生调用已释放的内存的情况)
//2.如果传递类对象,避免隐式类型转换,在创建线程时就构造临时对象,然后在函数参数里,最好用引用来接。(否则会拷贝构造两次)
//3.std::ref
//建议少使用detach,多使用join,这样就不存在局部变量失效导致线程对内存非法访问的问题
//void myprint(const int & i, char *pmybuf)
void myprint(const int i, const string pmybuf) //这样修改后可避免指向相同地址的问题,但在char数组转为string前可能就被系统回收了(主线程执行完毕)
{
cout << i << endl; //分析认为,i并不是mvar的引用,实际是值传递(复制,i和mvar的地址不一样)。那么可以认为,即使主线程detach了子线程,子线程的i依旧是安全的
cout << pmybuf << endl; //指针在detach时是绝对有问题的,所指的地址是相同的
return;
}
int main()
{
//1.传递临时对象作为线程参数
int mvar = 1;
int &mvary = mvar;
char mybuf[] = { "this is a test" };
thread mytobj(myprint, mvar, mybuf); //事实上,detach时,存在mybuf都被回收了(main函数执行完了),系统才用mybuf去转string的可能性(因为是在子线程中构造string对象)
thread mytobj(myprint, mvar, string(mybuf)); //直接将mybuf转换为string临时对象,这样可以保证线程中的mybuf一定有效(主线程中构造string对象,稳定)
thread mytobj(myprint, mvar, std::ref(mybuf)); //这样线程引用中的修改的值可影响到主线程的值(两个地址相同,不调用拷贝构造函数,那么detach时可能就会不安全(内存非法访问)) std::ref(mybuf)==&mybuf
//mytobj.join();
mytobj.detach();
cout << "主线程执行1" << endl;
return 0;
}