赞
踩
C++11 引入了 thread 类,大大降低了多线程使用的复杂度,原先使用多线程只能用系统的 API,无法解决跨平台问题,代码平台的改变,对应多线程代码也必须要修改。在 C++11 中只需使用语言层面的 thread 可以解决这个问题。编写并发程序需引入头文件<thread>
。
可以将本线程的 CPU 时间片放弃,并允许其他线程运行。
① yield 方法其实就是::Sleep(0)。
②Sleep 会交出 CPU 时间片,允许其他线程运行,但“其他线程”也包含了交出 CPU 时间片的那个线程。
③想要更好的进行线程切换,不能够使用 Sleep,而应采用线程锁或其他线程切换方法。
获取线程 ID,返回类型 std::thread::id 对象
template< class Rep, class Period >
void sleep_for( const std::chrono::duration<Rep, Period>& sleep_duration );
阻塞当前线程执行,至少经过指定的 sleep_duration 。此函数可能阻塞长于 sleep_duration ,因为调度或资源争议延迟。
template< class Clock, class Duration >
void sleep_until( const std::chrono::time_point<Clock,Duration>& sleep_time );
阻塞当前线程,直至抵达指定的 sleep_time 。
使用联倾向于 sleep_time 的时钟,这表示时钟调节有影响。从而在调用时间点后,阻塞的时长可能小于,但不会多于 sleep_time - Clock::now() 。函数亦可能阻塞长于抵达 sleep_time 之后,由于调度或资源争议延迟。
①默认构造函数:thread() noexcept
; 一个空的 std::thread 执行对象(无线程执行)
②初始化构造函数
template<class Fn, class... Args>
explicit thread(Fn&& fn, Args&&... args);
创建 std::thread 执行对象,线程调用 threadFun 函数,函数参数为 args。
线程在构造关联的线程对象时立即开始执行,从提供给作为构造函数参数的顶层函数开始(等待任何 OS 调度延迟)。顶层函数的返回值将被忽略,而且若它以抛异常终止,则调用 std::terminate 。
#include<thread>
using namespace std;
void threadFun(int a) // 值传递
{
cout << "this is thread fun !" <<endl;
cout <<" a = "<<a<<endl;
}
int main()
{
thread t1(threadFun, 2);
t1.join(); //等待线程完成其执行
cout<<"Main End "<<endl;
return 0;
}
thread(const thread&) = delete;
thread& operator=(const thread&) = delete;
拷贝构造函数被禁用,std::thread 对象不可拷贝构造,也不可以赋值。
thread( thread&& other ) noexcept;
thread& operator=( thread&& other ) noexcept;
调用成功原来 other 不再是 std::thread 对象
#include<thread> using namespace std; void threadFun(int &a) // 引用传递 { cout << "this is thread fun !" <<endl; cout <<" a = "<<(a+=10)<<endl; } int main() { int x = 10; thread t1(threadFun, std::ref(x)); thread t2(std::move(t1)); // t1 线程失去所有权 thread t3; t3 = std::move(t2); // t2 线程失去所有权 //t1.join(); // ? t3.join(); cout<<"Main End "<<"x = "<<x<<endl; return 0; }
①get_id()
:获取线程 ID,返回类型 std::thread::id 对象。
②join()
;创建线程执行线程函数,调用该函数会阻塞当前线程,直到线程执行完 join 才返回。
③detach()
; detach 调用之后,目标线程就成为了守护线程,驻留后台运行,与之关联的 std::thread 对象失去对目标线程的关联,无法再通过 std::thread 对象取得该线程的控制权。
④.joinable()
; 检查 std::thread 对象是否标识活跃(是指该线程的资源没有被释放)的执行线程,不会阻塞线程执行。
⑤swap()
;交换两个线程对象
thread t1(threadFun1);
thread t2(threadFun2);
cout << "线程 1 的 ID:" << t1.get_id() << endl;
cout << "线程 2 的 ID:" << t2.get_id() << endl;
t1.swap(t2);
cout << "线程 1 的 ID:" << t1.get_id() << endl;
cout << "线程 2 的 ID:" << t2.get_id() << endl;
⑥.hardware_concurrency()
; 静态函数,获得逻辑处理器储量,返回值为 int 型
int coreNum = thread::hardware_concurrency();
void threadFun(int x)
{
cout << "this is thread fun1 !" << endl;
cout << x << endl;
}
int main()
{
int value = 10;
thread ta(threadFun, value);
ta.join();
getchar();
return 0;
}
需要注意,变量 int value 和 int x 做变量传递时并不是引用,而是对变量做了拷贝,所以在传递给 int x 前,int value 不能出作用域(释放了内存),使用join(),可以保证 int value 变量释放内存,如果使用 detach(),可能存在这种情况
thread ta(threadFun1, std::ref(value));
using namespace std; class Object { private: int value; public: Object(int x = 0):value(x) { cout << "Constructor Object: "<<this << endl; } ~Object() { cout << "Destroy Object: "<<this<< endl; } void fun(string info) { cout << info << value<< endl; } }; int main() { Object obj; string str = "我是一个类的成员函数!"; thread t1(&Object::fun, &obj, str); t1.join(); getchar(); return 0; }
在线程间共享指针
void func(int x, int y,shared_ptr<int> pa) { std::this_thread::sleep_for(std::chrono::seconds(1)); // *pa = x + y; } int main() { int x = 10, y = 20; shared_ptr<int> pa(new int(0)); //使用共享型指针管理释放内存 //thread ta(func,x,y,std::ref(pa)); thread ta(func, x, y,pa); cout<<"before starting ... *pa: "<<*pa<<endl; cout<<"Cnt: "<<pa.use_count()<<endl; ta.join(); cout<<"after joining ... *pa: "<<*pa<<endl; cout<<"Cnt: "<<pa.use_count()<<endl; system("pause"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。