• C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)


    线程库C++11

    在C++ 11引入了对多线程的支持。包括线程、互斥锁、原子操作、自动加减锁和同步。下面就分别介绍一下对应的用法。

    线程Thread

    线程:系统分配cup时间和调度的基本单位

    头文件

    #include<thread>

    常用的成员函数

    函数名作用
    get_id()获取当前线程ID
    join()等待
    detach()分离

    创建线程的方式

    thread t1(函数地址);//无参
    thread t2(函数地址,参数1,参数2,…);//有参

    A a;
    thread t3(&A::output,&a);成员函数,

    全局函数实例:

    #include <thread>
    #include <string>
    #include <iostream>
    using namespace std;
     
    void test1(string name)//子线程 有参
    {
        for (int i = 0; i < 100; ++i)
        {
            cout << name <<  " test1:" << i << endl;
        }
    }
    void test2()//子线程
    {
        for (int i = 0; i < 100; ++i)
        {
            cout << "test2:" << i << endl;
        }
    }
     
     
    int main()
    {
        thread t1(test1, "线程1");//创建线程 并启动线程
        thread t2(test2);
     
        t1.join();//等待线程执行结束,不写会造成程序崩溃
        t2.join();
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    成员函数实例:

    class A
    {
    public:
        void output(string name)
        {
            cout << "线程执行 " << name << endl;
        }
    };
     
    int main()
    {
        A a;
     
        //格式:thread t1(函数地址 对象地址 参数1 参数2...)
        thread t1(&A::output, &a, "线程一");//成员函数做线程
     
        t1.join();
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    多线程的冲突问题

    a. 出现了更高等级的指令
    b. 该线程的时间片到了

    互斥体Mutex

    头文件

    #include<mutex>

    常用的成员函数

    函数名作用
    lock()加锁
    unlock()解锁

    实例

    #include <thread>
    #include <string>
    #include <iostream>
    #include <mutex>
    using namespace std;
     
    int g_a = 0;
    mutex g_m;//创建锁
     
    void test3()
    {
        for (int i = 0; i < 1000000; ++i)
        {
            //保证数据的完整性
            g_m.lock();//加锁
            g_a += 1;
            g_m.unlock();//解锁
        }
    }
     
    int main()
    {
        thread t1(test3);
        thread t2(test3);
        thread t3(test3);
     
        t1.join();
        t2.join();
        t3.join();
        cout << g_a << endl;
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    原子操作Atomic

    头文件

    #include<atomic>

    实例

    #include <thread>
    #include <iostream>
    #include <atomic>
    using namespace std;
     
    atomic_int a;//将这个变量设置为int原子级别
    void test3()
    {
        for (int i = 0; i < 1000000; ++i)
        {
            ++a;//在执行过程中,等同于锁
        }
    }
     
    int main()
    {
        thread t1(test3);
        thread t2(test3);
        thread t3(test3);
     
        t1.join();
        t2.join();
        t3.join();
        cout << a << endl;
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    自动加解锁lock_guard

    在创建时调用构造函数自动加锁,出了作用域就调用析构函数解锁。

    实例

    #include <thread>
    #include <string>
    #include <iostream>
    #include <mutex>
    #include <atomic>
    using namespace std;
     
    int a = 0;
    mutex g_m;//创建锁
    void test3()
    {
        for (int i = 0; i < 1000000; ++i)
        {
            lock_guard<mutex> la(g_m);//自动加锁 自动释放
            ++a;
            cout << a << endl;
        }
    }
     
    int main()
    {
        thread t1(test3);
        thread t2(test3);
        thread t3(test3);
     
        t1.join();
        t2.join();
        t3.join();
        cout << a << endl;
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    同步

    同步方式

    1. 信号量
    2. 事件
    3. 消息
    4. C++11中的条件变量

    实例

    #include <thread>
    #include <string>
    #include <iostream>
    #include <mutex>
    #include <atomic>
    #include <string>
    #include <condition_variable>
    using namespace std;
     
    string  buffer;
    mutex m; 
    condition_variable cv; //状态变量
    //为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起;
    void workThread()
    {
        //unique_lock比lock_guard灵活很多,效率上差一点,内存占用多一点。
        unique_lock<mutex> lk(m);
        cv.wait(lk);//等待信号
     
        cout << "收到数据:" << buffer << endl;
    }
     
    int main()
    {
        thread t1(workThread);
     
        string name;
        cin >> name;
     
        buffer = name;
        cv.notify_all();//发出通知
     
        t1.join();
        cout << "数据处理完成" << endl;
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
  • 相关阅读:
    python 爬取天气预报天气
    持续集成(二)Jenkins基本使用介绍
    Vue NextTick工作原理及使用场景
    做一个高中信息技术教资复习
    java计算机毕业设计Vue框架校园相约健康运动平台源码+mysql数据库+系统+lw文档+部署
    在Eclipse将Java代码打包为jar用于jmeter BeanShell
    zemax场曲与消场曲
    (已解决)在服务器(linux,centos)中调用R绘制图形之后保存报错,而在Windows中正常
    【LeetCode每日一题】——面试题17.16.按摩师
    线索二叉树
  • 原文地址:https://blog.csdn.net/qq_45254369/article/details/125509754