C++11线程库 (三) 创建一个线程

在文章C++11线程库 (一) 构造函数及其成员中我们知道我们有一下构造方法:

thread() noexcept;//since c++11
thread(thread&& other) noexcept;//since c++11
template<class Function,class ...Args>
explicit thread(Function &&f,Args && ...args);//since c++11
thread(const thread&)=delete;//since c++11

一共四个,第一个是默认构造,构造一个什么也不做的线程对象;第二个是std::move()会调用的移动构造函数;第三个是类模板,表示使用一个函数对象和若干个参数生成对应的线程类;第四个是拷贝构造函数,默认是不能拷贝的。

第三个是创建一个线程对象的基本方法,他需要

  • 一个函数对象
  • 零个或者多个参数

函数对象可以由函数模板产生,其定义:

template< class >
class function; /* undefined */
(since C++11)
template< class R, class... Args >
class function<R(Args...)>;//用R类实例化函数对象

给定一个类和对应参数,类模板产生一个std::function类。模板的class R参数有一定的要求,常见满足要求的类有:

  • 普通函数
  • lambda表达式
  • bind表达式
  • 其他可调用对象(如仿函数)
  • 成员函数指针
  • 成员函数数据成员(类数据成员?)

Notes
The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref).

Any return value from the function is ignored. If the function throws an exception, std::terminate is called. In order to pass return values or exceptions back to the calling thread, std::promise or std::async may be used.

实例:创建两个线程分别打印奇数和偶数

#include <iostream>
#include <thread>
using namespace std;

void show_even()
{
    
    
    for(int i=0;i<10;i+=2)
    {
    
    
        cout<<i;
    }   
};
void show_odd()
{
    
    
    for(int i=1;i<10;i+=2)
    {
    
    
        cout<<i;
    }
}
int main()
{
    
    
    thread th1(show_odd);
    thread th2(show_even);
    th1.join();
    th2.join();
    return 0;
}

每次运行的结果都不一样,任取三次结果:0246813579 1357902468 1350247968。cpu每次只会在一个线程中执行,如果处理的速度足够简单,可能一个线程所有内容完成了,另一个线程还没开始。

对于一个简单的执行内容,使用lambda创建一个可调用对象更为合适:

int main()
{
    
    
    thread th1([](){
    
    for(int i=0;i<10;i+=2){
    
    cout<<i;}});
    thread th2([](){
    
    for(int i=1;i<10;i+=2){
    
    cout<<i;}});
    th1.join();
    th2.join();
    return 0;
}

不用想函数名,不用专门写一个函数,blabla.

猜你喜欢

转载自blog.csdn.net/weixin_39258979/article/details/114193227