C++11多线程|互斥锁|条件变量|异步

文章目录

  • 线程thread
    • std::thread
    • 语法
      • 构造函数
      • 主要成员函数
      • 简单线程的创建
      • 线程封装
    • 互斥量
      • 独占互斥量std::mutex
        • std::mutex 介绍
        • std::mutex 的成员函数
      • 递归互斥量std::recursive_mutex
      • 带超时的互斥量std::timed_mutex和 std::recursive_timed_mutex
      • lock_guard和unique_lock的使用和区别
      • 总结
    • 条件变量
      • 成员函数
        • wait函数
        • wait_for函数
        • wait_until函数
        • notify_one函数
        • notify_all函数
      • 范例
    • 原子变量
    • call_once和once_flag使用
    • 异步操作
      • std::future
        • future的类型
        • future的使用
      • std::packaged_task
      • std::promise
      • 总结
    • Reference
      • 总结
    • Reference

线程thread

#项目地址:https://github.com/Phoenix8215/CplusplusMagicalCrafts

std::thread

#include头文件中声明,因此使用 std::thread 时需要包含**#include** 头文件。

语法

构造函数

  • 默认构造函数
//创建一个空的 thread 执行对象。
thread() _NOEXCEPT
{ // construct with no thread
    _Thr_set_null(_Thr);
}
  • 初始化构造函数
//创建std::thread执行对象,该thread对象可被joinable,新产生的线程会调用threadFun函数,该函
数的参数由 args 给出
    template
        explicit thread(Fn&& fn, Args&&... args);
  • 拷贝构造函数
// 拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。
thread(const thread&) = delete;
  • Move构造函数
//move 构造函数,调用成功之后 x 不代表任何 thread 执行对象。
//注意:可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为
detached。
thread(thread&& x)noexcept

主要成员函数

  • get_id()
    • 获取线程ID,返回类型std::thread::id对象。
    • http://www.cplusplus.com/reference/thread/thread/get_id/
  • joinable()
    • 判断线程是否可以加入等待
    • http://www.cplusplus.com/reference/thread/thread/joinable/
  • join()
    • 等该线程执行完成后才返回。
    • http://www.cplusplus.com/reference/thread/thread/join/
  • detach()
    • 将本线程从调用线程中分离出来,允许本线程独立执行。(但是当主进程结束的时候,即便是 detach()出去的子线程不管有没有完成都会被强制杀死)
    • http://www.cplusplus.com/reference/thread/thread/detach/

简单线程的创建

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

#include 
#include 
using namespace std;
void func1()
{
    cout << "func1 into" << endl;
}
void func2(int a, int b)
{
    cout << "func2 a + b = " << a+b << endl;
}
class A
{
    public:
    static void fun3(int a)
    {
        cout << "a = " << a << endl;
    }
};
int main()
{
    std::thread t1(func1); // 只传递函数
    t1.join(); // 阻塞等待线程函数执行结束
    int a =10;
    int b =20;
    std::thread t2(func2, a, b); // 加上参数传递
    t2.join();
    std::thread t3(&A::fun3, 1); // 绑定类静态函数
    t3.join();
    return 0;
}

线程封装

见范例1-thread2-pack zero_thread.h

zero_thread.h

#ifndef ZERO_THREAD_H
#define ZERO_THREAD_H
#include 
class ZERO_Thread
{
    public:
    ZERO_Thread(); // 构造函数
    virtual ~ZERO_Thread(); // 析构函数
    bool start();
    void stop();
    bool isAlive() const; // 线程是否存活.
    std::thread::id id() { return _th->get_id(); }
    std::thread* getThread() { return _th; }
    void join(); // 等待当前线程结束, 不能在当前线程上调用
    void detach(); //能在当前线程上调用
    static size_t CURRENT_THREADID();
    protected:
    static void threadEntry(ZERO_Thread *pThread); // 静态函数, 线程入口
    virtual void run() = 0; // 运行
    protected:
    bool _running; //是否在运行
    std::thread *_th;
};
#endif // ZERO_THREAD_H

zero_thread.cpp

#include "zero_thread.h"
#include 
#include 
#include 
ZERO_Thread::ZERO_Thread():
_running(false), _th(NULL)
{
}
ZERO_Thread::~ZERO_Thread()
{
    if(_th != NULL)
    {
        //如果资源没有被detach或者被join,则自己释放
        if (_th->joinable())
        {
            _th->detach();
        }
        delete _th;
        _th = NULL;
    }
    std::cout << "~ZERO_Thread()" << std::endl;
}
bool ZERO_Thread::start()
{
    if (_running)
    {
        return false;
    }
    try
    {
        _th = new std::thread(&ZERO_Thread::threadEntry, this);
    }
    catch(...)
    {
        throw "[ZERO_Thread::start] thread start error";
    }
    return true;
}
void ZERO_Thread::stop()
{
    _running = false;
}
bool ZERO_Thread::isAlive() const
{
    return _running;
}
void ZERO_Thread::join()
{
    if (_th->joinable())
    {
        _th->join();
    }
}
void ZERO_Thread::detach()
{
    _th->detach();
}
size_t ZERO_Thread::CURRENT_THREADID()
{
    // 声明为thread_local的本地变量在线程中是持续存在的,不同于普通临时变量的生命周期,
    // 它具有static变量一样的初始化特征和生命周期,即使它不被声明为static。
    static thread_local size_t threadId = 0;
    if(threadId == 0 )
    {
        std::stringstream ss;
        ss << std::this_thread::get_id();
        threadId = strtol(ss.str().c_str(), NULL, 0);
   

你可能感兴趣的:(C++,c++,开发语言,算法,数据结构)