• std::thread 学习笔记


    std::thread

    创建线程(基本)

    #include <bits/stdc++.h>
    using namespace std;
    
    void a()
    {
        for (int i = 0; i < 10; i++)
            cout << "a";
    }
    void b(bool flag)
    {
        for (int i = 0; i < 10; i++)
            cout << (flag ? "c" : "b");
    }
    
    signed main()
    {
        thread ta(a);
        thread tb(b, 0);
        thread tc(b, 1);
        // 等待子线程执行完再退出
        ta.join();
        tb.join();
        tc.join();
        cout << "m" << endl;
    }
    

    线程对象执行了join后就不再joinable了,所以只能调用join一次

    传引用时需要 std::ref

    互斥量 mutex

    构造函数,std::mutex不允许拷贝构造

    lock(),调用线程将锁住该互斥量

    注意:如果当前互斥量被其他线程锁住,则当前的调用线程被阻塞住;如果当前互斥量被当前调用线程锁住,则会产生死锁

    unlock(), 解锁

    try_lock(),尝试锁住互斥量,如果互斥量被其他线程占有,则当前线程也不会被阻塞。但是,如果当前互斥量被当前调用线程锁住,依然会产生死锁

    #include <bits/stdc++.h>
    using namespace std;
    
    mutex m;
    int cnt = 0;
    
    void a()
    {
        while (cnt < 5000)
        {
            m.lock();
            ++cnt;
            cout << "a: " << cnt << "	";
            m.unlock();
        }
    }
    void b()
    {
        while (cnt < 5000)
        {
            m.lock();
            ++cnt;
            cout << "b: " << cnt << "	";
            m.unlock();
        }
    }
    
    signed main()
    {
        thread ta(a);
        thread tb(b);
        // 等待子线程执行完再退出
        ta.join();
        tb.join();
        cout << "m" << endl;
    }
    

    使用mutex是不安全的,当一个线程在解锁之前异常退出了,那么其它被阻塞的线程就无法继续下去

    使用 lock_guard

    能够自解锁,该对象创建时,它会像m.lock()一样获得互斥锁,当生命周期结束时,它会自动析构(unlock)

    #include <bits/stdc++.h>
    using namespace std;
    
    mutex m;
    int cnt = 0;
    
    void a()
    {
        while (cnt < 5000)
        {
            lock_guard<mutex> lgmutex(m);
            ++cnt;
            cout << "a: " << cnt << "	";
        }
    }
    void b()
    {
        while (cnt < 5000)
        {
            lock_guard<mutex> lgmutex(m);
            ++cnt;
            cout << "b: " << cnt << "	";
            if (cnt > 4000)
                break;
        }
    }
    
    signed main()
    {
        thread ta(a);
        thread tb(b);
        // 等待子线程执行完再退出
        ta.join();
        tb.join();
        cout << "m" << endl;
    }
    
  • 相关阅读:
    《OOAD与UML那点儿事》目录索引
    《BI那点儿事—数据的艺术》目录索引
    《BI项目笔记》——微软BI项目笔记连载
    VC++常用数据类型转化
    模式识别—最邻近模板匹配法
    C#引用C++开发的DLL
    图像预处理第9步:存为.bmp文件
    图像预处理第8步:紧缩重排数字字符
    图像预处理第7步:标准归一化
    图像预处理第5步:倾斜度调整
  • 原文地址:https://www.cnblogs.com/mollnn/p/14439224.html
Copyright © 2020-2023  润新知