- 传递临时对象
- 陷阱
- 总结
- 临时对象做为线程参数
- 线程id的概念
- 临时对象构造时的抓捕
- 成员函数指针作线程函数
传递临时对象做为线程参数
建立的工做线程不止一个,线程根据编号来肯定工做内容。每一个线程都须要知道本身的编号。线程中有不少容易犯错的写法ios
例子1安全
多线程须要执行的函数:多线程
void my_print(const int &i, char* p_mybuff) { cout << i << endl; cout << p_mybuff << endl; return ; }
主函数的写法函数
int mvar = 1; int& mvary = mvar; char mybuf[] = "this is a test!"; thread myobj(my_print, mvar, mybuf); myobj.join(); cout << "Main Thread!!!" << endl;
解释:注意陷阱!!!引用和指针的变量传参。this
引用:表面看起来彷佛正确,可是细节上有不少地方须要注意的,若是把join()改为detach(),而后主线程和子线程分别执行,那么可能出现主线程执行完了,可是传递进去的参数(引用形式)的资源已经被释放了,有没有可能出现错误?:spa
myobj.detach()
在建立thread对象的时候,作了一个复制,把值复制进去了,因此不是一个真引用,实际是值传递,不会出现资源释放的错误。可是反过来想,那么主线程的变量的值并不会改变。操作系统
指针:若是传递的参数是指针,第二个参数不安全,若是用detach()执行线程的时候,不推荐用“引用”,指针绝对会有问题!线程
正确的用法是什么样:不传引用,若是要传字符串的状况。指针
char* p_mybuff 改为 const string &p_mybuff ,确实不指向于同一块内存,何时出现了变量类型的转换?事实上存在主函数执行完了,p_mybuff 都被回收了,系统才用p_mybuff 去转换stringcode
thread myobj(my_print, mvar, string(mybuf));
若是用一个string 去强制类型转换,生成一个临时对象,此时的临时对象会绑定到p_mybuff上。在建立线程的时候,构造临时变量的方法传递参数是可行的,此时也会调用一次构造函数,此时detach也能正确运行。为了防止主线程退出,子线程内存的非法引用。
1) 对传递int,直接用值传递。
2) 若是传递类对象,避免隐式类型转换。所有都在建立线程的时候就构建出临时对象,在函数参数里用引用来接收传递的函数。不然系统还会多构造一次函数,形成没必要要的浪费。
3) 主线程中类型转换,那么A(mysecondpar) 这一步由主线程操做
thread myobj(myprint, mvar, A(mysecondpar));
thread myobj(myprint, mvar, mysecondpar);
4) 建议不使用detach,用join
传递临时对象做为线程参数
线程ID:在操做系统的层面须要调度线程,有一个线程ID,以及线程ID的文件描述符,用来管理这个线程的资源分配。在线程之间须要调度,因此也有优先级的概念。每一个线程对应一个ID,线程ID能够用C++标准库里面的函数来获取 std::this_thread::get_id()。
传参函数给线程的时候,参数入口都是const,在函数中const不能修改,若是须要修改变量,就在初始化的时候“mutable”。在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,可是在多线程里面也有问题,若是真的要修改值,那么就使用std:ref(),这个ref和在C#里面是相似的,将方法内的变量改变后带出方法外,用std:ref(),真正地把变量传进去。
完整的代码:
#include "pch.h" #include <iostream> #include <thread> using namespace std; class person { public: int m_age; person(int a) :m_age(a) { cout << "person 的构造函数,进程为:" << std::this_thread::get_id()<<endl; } person(const person &p) :m_age(p.m_age) { cout << "person 的复制构造函数 " << std::this_thread::get_id() << endl; } ~person() { cout << "person的析构函数 " << std::this_thread::get_id() << endl; } }; void myprin(const int &num, char *p[]) { cout << "如今的线程是: " << std::this_thread::get_id() << endl; cout << "传入的参数是:" << endl; cout << num << " " << p << endl; } void print_class(person p) { cout << "如今的线程是: " << std::this_thread::get_id() << endl; cout << "print class: " << p.m_age << endl; } int main() { std::cout << "主线程: "<< std::this_thread::get_id()<<endl; int num = 1; //person student(num); thread obj(print_class, person(10)); }
传递成员函数到线程中
将类的成员函数传递到线程中。
std::thread myobj(&classA::method, para1, para2,..); myobj.join();
classA::method就是一个函数。