C++11 介绍 thread
本文章的目的是记录自己在学习C++11多线程模块之中的练习。
2014-01-19
Thread
Class to represent individual threads of execution.
A thread of execution is a sequence of instructions that can be executed concurrently with other such sequences in multithreading environments, while sharing a same address space.
An initialized thread object represents an active thread of execution; Such a thread object is joinable, and has a unique thread id.
A default-constructed (non-initialized) thread object is not joinable, and its thread id is common for all non-joinable threads.
A joinable thread becomes not joinable if moved from, or if either join or detach are called on them.
--------------------------------------------------------
| Member types | |
| id | Thread id (public member type ) |
| native_handle_type | Native handle type (public member type ) |
| Member functions | |
| (constructor) | Construct thread (public member function ) |
| (destructor) | Thread destructor (public member function ) |
| operator= | Move-assign thread (public member function ) |
| get_id | Get thread id (public member function ) |
| joinable | Check if joinable (public member function ) |
| join | Join thread (public member function ) |
| detach | Detach thread (public member function ) |
| swap | Swap threads (public member function ) |
| native_handle | Get native handle (public member function ) |
| hardware_concurrency [static] | Detect hardware concurrency (public static member function ) |
从Menber functions说起:
(constructor) 构造函数 负责线程对象的初始化构造。
(destructor) 析构函数 负责线程对象的销毁。
operator= 等于赋值运算符,采用付给 = 号左侧对象一个右值。
这是thread模块的等于运算符的声明
thread& operator=(thread&& _Other) _NOEXCEPT //函数传递的参数是--右值引用,移动赋值运算符 调用 默认的移动构造函数。因为不抛出任何异常,所以加上了noexcept声明。 { // move from _Other return (_Move_thread(_Other)); } thread(const thread&) = delete; //参数为常引用 是默认删除的。 thread& operator=(const thread&) = delete; //返回类型为引用,参数为常引用 是默认删除的。
测试代码如下
std::thread threads[5]; std::cout << "创建5个线程"<<endl; for (int i = 0; i<5; ++i) threads[i] = thread(pause_thread, i + 1); // 移动赋值构造函数 std::cout << "线程创建完毕,等待这5个线程join()"<<endl; for (int i = 0; i<5; ++i) threads[i].join(); std::cout << "所有线程完成join()\n";
测试结果
----------------------------------------------------------------------------
创建5个线程
线程创建完毕,等待这5个线程join()
暂停 1 s
暂停 2 s
暂停 3 s
暂停 4 s
暂停 5 s
所有线程完成join()
请按任意键继续. . .----------------------------------------------------------------------------
detach() 字面意识是--分离,使线程和主线程独立,主线程结束时不在等待线程是否结束。
测试代码如下:
cout << "创建 3 个线程.\n"; thread t1(pause_thread\n"; thread(pause_thread, 1).detach(); thread(pause_thread, 2).detach(); thread(pause_thread, 3).detach(); cout << "创建完成三个线程\n"; cout << "(主线程暂停5秒)\n"; // 给分离的线程时间,让他们完成自己的操作 (但这并不是守护线程!!!): pause_thread(5);测试结果:
创建 3 个线程.
创建完成三个线程
(主线程暂停5秒)
暂停 1 s
暂停 2 s
暂停 3 s
暂停 5 s
请按任意键继续. . .
get_id 获得当前线程的id号。
joinable() 判断当前线程是否可以join(),如果可以join()则返回1,否则返回0。
join() join()当前线程,有句解释是 The function returns when the thread execution has completed. 如果线程执行完毕,返回该线程调用的函数。也就是结束线程调用的函数的意思。
swap() 交换线程,如t1.swap(t2)。
native_handle() 返回当前句柄,句柄指的是一个核心对象在某一个进程中的唯一索引。
hardware_concurrency() 返回当前设备线程数,如i7,返回unsigned int 类型 8。
测试代码
cout << "创建 3 个线程.\n"; thread t1(pause_thread, 1); thread t2(pause_thread, 2); thread t3(pause_thread, 3); cout << t1.native_handle() << endl; cout << t2.native_handle() << endl; cout << t3.native_handle() << endl; //输出三个线程的句柄信息 cout << t1.hardware_concurrency() << endl; cout << t2.hardware_concurrency() << endl; cout << t3.hardware_concurrency() << endl; //输出当前硬件线程信息 cout << "创建线程完成 现在等待他们join():\n"; cout <<"t1 "<< test_joinable(&t1)<< endl; cout << "running t1.join()" << endl; t1.join(); cout <<"t1 "<< test_joinable(&t1) << endl; cout << "-------------------------" << endl; //判断t1是否可以join(),调用的是个一个test_joinable()函数,返回是t.joinable()的返回值 cout << "t2 " << test_joinable(&t2) << endl; cout << "running t2.join()" << endl; t2.join(); cout << "t2 " << test_joinable(&t2) << endl; cout << "-------------------------" << endl; cout << "t3 " << test_joinable(&t3) << endl; cout << "running t3.join()" << endl; t3.join(); cout << "t3 " << test_joinable(&t3) << endl; cout << "所有线程join()\n";
测试结果如下:
创建 3 个线程.
0000009C
000000A8
000000B4
8
8
8
创建线程完成 现在等待他们join():
t1 可以阻塞
running t1.join()
暂停 1 s
t1 不可以阻塞
-------------------------
t2 可以阻塞
running t2.join()
暂停 2 s
t2 不可以阻塞
-------------------------
t3 可以阻塞
running t3.join()
暂停 3 s
t3 不可以阻塞
所有线程join()
请按任意键继续. . .
命名空间std::this_thread下的函数
get_id Get thread id (function )
yield Yield to other threads (function )
sleep_until Sleep until time point (function )
sleep_for Sleep for time span (function )
get_id std::this_thread下的函数,在函数内调用,可以返回调用当前函数的线程号。
测试代码:
thread t1(pause_thread, 1); Sleep(50); thread t2(pause_thread, 2); Sleep(50); thread t3(pause_thread, 3); cout << "t1.get_id() " << t1.get_id() << endl; cout << "t2.get_id() " << t2.get_id() << endl; cout << "t3.get_id() " << t3.get_id() << endl; t1.join(); t2.join(); t3.join(); std::cout << "所有线程join()\n";测试结果:
this_thread::get_id() ---9024
this_thread::get_id() ---8220
this_thread::get_id() ---4012
t1.get_id() 9024
t2.get_id() 8220
t3.get_id() 4012
暂停 1 s
暂停 2 s
暂停 3 s
所有线程join()
请按任意键继续. . .
yield std::this_thread下的函数,暂时放弃一段 CPU 时间、让给其他线程使用。
测试代码:(比较哪个线程先算完1-100w的计数)
std::atomic<bool> ready(false); void count1m(int id) { while (!ready) //现在ready 是 false 那么 !ready 就是 真,所以无限循环执行 this_thread::yield(); { // wait until main() sets ready... this_thread::yield(); } for (volatile int i = 0; i<1000000; ++i) {} std::cout << id; } void main() { thread threads[10]; cout << "race of 10 threads that count to 1 million:\n"; for (int i = 0; i<10; ++i) threads[i] = std::thread(count1m, i); for (auto& th : threads) cout <<th.get_id() << endl; ready = true; // go! for (auto& th : threads) th.join(); cout << '\n'; }测试结果:
race of 10 threads that count to 1 million:
0382916754
请按任意键继续. . .所以,第一算完的是0号线程,第二名是3号,第三名是8号……
sleep_until std::this_thread下的函数,设置一个绝对时刻、让运行线程在指定的时刻后再继续运行。
sleep_for std::this_thread下的函数,停止一段指定的时长的执行。
void main() { cout << "countdown:\n"; for (int i = 10; i>0; --i) { cout << i << '\n'; this_thread::sleep_for(chrono::seconds(1)); //相当于windows.h Sleep(1000) } cout << "Lift off!\n"; }sleep_for()
未完待续...
浙公网安备 33010602011771号