C++11多线程---线程(一)

系列文章目录

C++11多线程---线程(一)

C++11多线程---互斥锁(二)

C++11多线程---条件变量(三)

C++11多线程---原子操作变量(四)

C++11多线程---异步操作(五)


前言

C++11 引入了 thread 类,降低了使用多线程的复杂度,原先使用多线程只能用系统的 API,无法解决跨平台问题,代码平台的改变,对应多线程代码也必须要修改。在 C++11 中只需使用语言层面的 thread 可以解决这个问题。编写并发程序需引入头文件<thread>。 

一、线程thread

1、语法

1.1 构造函数

默认构造函数

//创建一个空的 thread 执行对象。

thread() _NOEXCEPT

{         // construct with no thread

        _Thr_set_null(_Thr);

}

初始化构造函数

//创建std::thread执行对象,该thread对象可被joinable,新产生的线程会调用threadFun函数,该函数的参数由 args 给出

template<class Fn, class... Args>

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

拷贝构造函数

// 拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。

thread(const thread&) = delete;

Move构造函数 

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

注意:可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为

detached。

thread(thread&& x)noexcept

// 构造函数的使用

#include <iostream>

#include <thread>

using namespace std;

void threadFun(int &num)    // 引用传递

{

    cout << "this is thread fun !" <<endl;

    cout <<" num = "<<num<<endl;

}

int main()

{

    int num = 10;

    thread t1(threadFun, std::ref(num));  // 引用传递

    thread t2(std::move(t1));           // t1 线程失去所有权

    thread t3;

    t3 = std::move(t2);                 // t2 线程失去所有权

    // t1.join(); // 会出错,因为t1已被move

    t3.join();

    cout<<"last num is "<<num<<endl;

    return 0;

}

1.2 主要成员函数  

简单线程的创建

使用std::thread创建线程,提供线程函数或者函数对象,并可以同时指定线程函数的参数。

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

void func1()
{
    cout << "func1" << endl;
}


void func2(int a, int b)
{
    cout << "func2 a + b = " << a+b << endl;
}


void func3(int &c) // 引用传递
{
    cout << "func3 c = " << &c << endl;
    c += 1;
}

class A
{
 
public:
    // 4. 传入类函数
    void func4(int a)
    {
        // std::this_thread::sleep_for(std::chrono::seconds(1));
        cout << "thread:" << name_<< ", fun4 a = " << a << endl;
    }
    void setName(string name) {
        name_ = name;
    }
    void displayName() {
        cout << "this:" << this << ", name:" << name_ << endl;
    }
    void play()
    {
        std::cout<<"play call!"<<std::endl;
    }
private:
    string name_;
};

//5. detach
void func5()
{
    cout << "func5" << endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
    cout << "func5 leave " << endl;
}

// 6. move
void func6()
{
    cout << "func6" <<endl;
}

int main()
{
    // 1. 传入0个值
    cout << "\n\n main1--------------------------\n";
    std::thread t1(&func1); // 只传递函数
    t1.join(); // 阻塞等待线程函数执行结束
    
    // 2. 传入2个值
    cout << "\n\n main2--------------------------\n";
    int a =10;
    int b =20;
    std::thread t2(func2, a, b); // 加上参数传递,可以任意参数
    t2.join();
    
    // 3. 传入引用
    cout << "\n\n main3--------------------------\n";
    int c =10;
    std::thread t3(func3, std::ref(c)); // 加上参数传递,可以任意参数
    t3.join();
    cout << "main3 c = " << &c << ", "<<c << endl;
    
    // 4. 传入类函数
    cout << "\n\n main4--------------------------\n";
    A * a4_ptr = new A();
    a4_ptr->setName("darren");
    std::thread t4(A::func4, a4_ptr, 10);
    t4.join();
    delete a4_ptr;
    
    // 5.detach
    cout << "\n\n main5--------------------------\n";
    std::thread t5(&func5); // 只传递函数
    t5.detach(); // 脱离
    // std::this_thread::sleep_for(std::chrono::seconds(2)); // 如果这里不休眠会怎么样
    cout << "\n main5 end\n";
    
    // 6.move
    cout << "\n\n main6--------------------------\n";
    int x = 10;
    thread t6_1(func6);
    thread t6_2(std::move(t6_1)); // t6_1 线程失去所有权
    t6_1.join(); // 抛出异常
    t6_2.join();
    
    return 0;
}

3、补充

this_thread - C++ Reference (cplusplus.com)

  • get_id :Get thread id (function )
  • yield :Yield to other threads (function ),比如范例:yield - C++ Reference (cplusplus.com)
  • sleep_until :Sleep until time point (function )
  • sleep_for :Sleep for time span (function )

总结

本文仅仅简单介绍了c++11线程的基本使用以及相关的API调用。

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值