boost并发编程——多线程

原子操作,基本都包含我们三个方面所关心的语义:
– 操作本身是不可分割的(Atomicity),
– 一个线程对某个数据的操作何时对另外一个线程可见(Visibility),
– 执行的顺序是否可以被重排(Ordering)。

#include <boost/atomic.hpp>  
#include <vector>
#include <iostream>   

using namespace std;
using namespace boost;


int main()
{
    atomic<int> a(10);
    assert(a == 10);

    atomic<long> b;  //未初始化危险!!
    cout << b << endl;
    //最重要的2成员函数store()  load();以原子的方式存取atomic内部值;
    atomic<bool> c(false);
    assert(!c.load()); //取值

    c.store(1);        //存值
    assert(c.load());

    //exchange() 原子地交换两个值,存值后返回atomic内部原有的值
    assert(a.exchange(100) == 10);
    assert(a.load() == 100);
    assert(a == 100);

    system("pause");
    return 0;
}

使用mutex,潜在风险是程序中途奔溃,常常使用lock_guard辅助使用mutex,保证mutex 自动析构
mutex未能及时unlock,lock() try_lock_timed() try_lock_until() 是阻塞的,try_lock() 非阻塞,返回bool类型

#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp> 
#include <boost/atomic.hpp>
#include <boost/thread/lockable_adapter.hpp>
#include <boost/thread/lock_factories.hpp>
#include <vector>
#include <iostream>   

using namespace std;
using namespace boost;

//account继承lockable_adapter<mutex>,所以account有了mutex的接口,可以像互斥量一样使用
class account : public lockable_adapter<mutex>
{
private:
    atomic<int> m_money{ 0 };

public:
    account() {}
    ~account() {}
    int sum()const {
        return m_money;
    }
    void withdraw(int x) {
        m_money = m_money - x;
    }
    void deposit(int x) {
        m_money += x;
    }

};
int main()
{
    account a;
    {
        //unique_lock<Lockable> make_unique_lock(Lockable& mtx);
        //unique_lock<Lockable> make_unique_lock(Lockable& mtx,try_to_lock);

        auto g = make_unique_lock(a);//无须其他mutex
        a.deposit(100);
        a.withdraw(20);
        assert(a.sum() == 80);
        cout << a.sum() << endl;
    }
    //g 大括号必须加,出了作用于 互斥锁自动解析,否则b ,没法 锁定

    {
        auto b = make_unique_lock(a, try_to_lock);
        if (b)
        {
            a.withdraw(a.sum());
            assert(a.sum() == 0);
            cout << a.sum() << endl;
        }
    }


    ::system("pause");
    return 0;
}
#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp> 
#include <boost/atomic.hpp>
#include <boost/thread/lockable_adapter.hpp>
#include <boost/thread/lock_factories.hpp>
#include <vector>
#include <iostream>   

using namespace std;
using namespace boost;


int main()
{
    mutex m1, m2;
    {
        auto g1 = make_unique_lock(m1, adopt_lock);
        auto g2 = make_unique_lock(m2, adopt_lock);
        //constexpr adopt_lock_t adopt_lock = {}; 编译期 常量标志
        //adopt_lock : is_locked = true  不执行锁定操作
        lock(m1, m2);//最多5个,锁定2个mutex
        //lock() 区别于mutex.lock() 可以一次锁定最多5个mutex
    }
    //unique_lock 自动解锁

    {
        auto g1 = make_unique_lock(m1, defer_lock); //推迟锁定
        auto g2 = make_unique_lock(m2, defer_lock);
        try_lock(g1, g2); //锁定2个unique_lock
    }
    //unique_lock 自动解锁



    ::system("pause");
    return 0;
}
#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp> 
#include <boost/chrono.hpp>
#include <boost/thread/lockable_adapter.hpp>
#include <boost/thread/lock_factories.hpp>
#include <vector>
#include <iostream>   

using namespace std;
using namespace boost;

void dummy(int n)
{
    for (int i = 0; i <= n; i++)
        cout << "dummy for x " << n << endl;
}
int main()
{
    //从某种程度上说,线程就是在进程的另一个空间里运行的一个函数
    //因此线程的创建需要传递thread对象一个无惨的可调用物——函数、函数对象、bind/lambda表达式,
    //它必须具有operator()以供线程执行
    //thread的构造函数使用的是参数的拷贝,因此要求可调用物和参数都是支持拷贝构造
    //thread对象 在析构时会调用std::terminate结束线程的执行,并不关心线程是否执行结束
    //所以保证线程正确运行,需要调用join() 等待线程执行结束,或者调用detach()分离线程体

    //创建thread对象后,会立即执行,不提供start()  或者 begin()方法
    thread t1(dummy, 10);
    thread t2(dummy, 20);

    //cout << t1.get_id() << endl;
    //cout << t2.get_id() << endl;  //{Not-any-thread}
    //assert(t1.get_id() == t2.get_id());
    //cout << thread::hardware_concurrency() << endl; //cpu 内核数量
    //cout << thread::physical_concurrency() << endl; //真实的物理cpu核心数量
    ////4个自由函数,无须thread对象即可操作当前线程,
    ////位于子名称空间boost::this_thread
    //boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
    if (t1.joinable())
        t1.join();
    if (t2.joinable())
        t2.join();
    //bool joinable() 判断thread对象是否标识了一个可执行的线程体,即可调用的函数
    //join()阻塞等待线程结束,谁来等!!!主线程
    //所以t1 t2依旧如此杂乱

    //detach() 分离线程对象和线程体,此后thread对象不代表任何线程体,Joinable() == false
    //detach分离,不影响线程执行体继续执行,直到函数结束或者主线程结束

    ::system("pause");
    return 0;
}

看看这凌乱的结果

dummy for x 10
dummy for x 20
dummy for x 10
dummy for x 20dummy for x 10

dummy for x dummy for x 2010

dummy for x dummy for x 2010

dummy for x dummy for x 2010

dummy for x dummy for x 2010

dummy for x dummy for x 2010

dummy for x dummy for x 1020

dummy for x 10dummy for x 20

dummy for x 10dummy for x 20

dummy for x 20
dummy for x 20
dummy for x 20
dummy for x 20
dummy for x 20
dummy for x 20
dummy for x 20
dummy for x 20
dummy for x 20
dummy for x 20
dummy for x 20

分离线程

#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp> 
#include <boost/chrono.hpp>
#include <boost/thread/lockable_adapter.hpp>
#include <boost/thread/lock_factories.hpp>
#include <vector>
#include <iostream>   

using namespace std;
using namespace boost;

void dummy(int n)
{
    for (int i = 0; i <= n; i++)
        cout << "dummy for x " << n << endl;
}
int main()
{
    thread t1(dummy, 10);
    t1.detach();;
    assert(!t1.joinable());
    //thread((dummy,100).detach())   临时线程,执行后自动分离


    ::system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35508344/article/details/80989110