C++11 多线程学习----std::thread类的简单使用

来源:互联网 发布:电脑vr软件 编辑:程序博客网 时间:2024/04/28 02:09

一 C++11多线程简介

    C++11标准库会提供类threadstd::thread)。若要运行一个线程,可以创建一个类thread的实体,其初始参数为一个函数对象,以及该函数对象所需要的参数。通过成员函数std::thread::join()对线程会合的支持,一个线程可以暂停直到其它线程运行完毕。若有底层平台支持,成员函数std::thread::native_handle()将可提供对原生线程对象运行平台特定的操作。对于线程间的同步,标准库将会提供适当的互斥锁(像是std::mutexstd::recursive_mutex等等)和条件参数(std::condition_variablestd::condition_variable_any)。前述同步机制将会以RAII锁(std::lock_guardstd::unique_lock)和锁相关算法的方式呈现,以方便程序员使用。

对于要求高性能,或是极底层的工作,有时或甚至是必须的,我们希望线程间的通信能避免互斥锁使用上的开销。以原子操作来访问内存可以达成此目的。针对不同情况,我们可以通过显性的内存屏障改变该访问内存动作的可见性。

对于线程间异步的传输,C++11标准库加入了以及std::packaged_task用来包装一个会传回异步结果的函数调用。因为缺少结合数个future的功能,和无法判定一组promise集合中的某一个promise是否完成,futures此一提案因此而受到了批评。

更高级的线程支持,如线程池,已经决定留待在未来的TechnicalReport加入此类支持。更高级的线程支持不会是C++11的一部分,但设想是其最终实现将创建在目前已有的线程支持之上。

     std::async提供了一个简便方法以用来运行线程,并将线程绑定在std::future。用户可以选择一个工作是要多个线程上异步的运行,或是在一个线程上运行并等待其所需要的数据。默认的情况,实现可以根据底层硬件选择前面两个选项的其中之一。另外在较简单的使用情形下,实现也可以利用线程池提供支持。

 

二 简单std::thread的使用

        

#include <iostream>#include <thread> using namespace std; void myFirstThread(){         cout << "Hello thread" << endl;} int main(){         thread myThread(myFirstThread);         myThread.join();         return 0;}


三 std::thread类构造函数函数简介

  

std::thread构造

1 默认构造,创建一个空的thread对象,以下为默认构造函数声明:

thread() noexcept;

2拷贝构造 copy-delete(thread对象不可拷贝构造)

thread (const thread&) = delete;

3初始化构造,创建thread对象,该对象可被joinable,线程会调用fn函数,参数由args给出,下边为初始化构造   函数声明:

template <class Fn, class... Args>

explicit thread (Fn&& fn,Args&&... args);

4移动构造 move此构造函数调用成功之后,x不代表任何thread可执行对象。

thread (thread&& x) noexcept;

注意:可被joinable的thread对象必须在他们销毁之前被主线程join或者将之设置为detached。
 
std::thread各种构造函数示例如下:
#include <iostream>#include <thread>using namespace std;void myFirstThreadTask(int num){for (int i = 0; i < 10; ++i){cout << "myFirstThreadTask's num = " << num++ << endl;this_thread::sleep_for(chrono::milliseconds(10));}}void mySecondThreadTask(int &num){for (int i = 0; i < 10; ++i){cout << "mySecondThreadTask's num = " << num++ << endl;this_thread::sleep_for(std::chrono::milliseconds(10));}}int main(int argc, _TCHAR* argv[]){int n = 5;thread myThread0;//myThread1为一个空线程,不代表任何可执行对象//myThread1与myFirstThreadTask函数绑定,n为其按值传递参数thread myThread1(myFirstThreadTask,n);//myThread2与mySecondThreadTask函数绑定,n为其引用传递参数thread myThread2(mySecondThreadTask,std::ref(n));//现在myThread2不代表任何可执行对象,myThread3与mySecondThreadTask函数绑定thread myThread3(std::move(myThread2));myThread1.join();myThread3.join();//myThread3.join();return 0;}




0 0
原创粉丝点击