Блокировка операции копирования std :: shared_ptr внутри лямбды - PullRequest
1 голос
/ 21 января 2020

Для этого примера кода:

#include <iostream>
#include <thread>
#include <mutex>
#include <memory>

struct A
{
    int _i;
    A(int i):_i(i)
    {
        std::cout<<"A() "<<_i<<std::endl;
    }
    ~A()
    {
        std::cout<<"~A() "<<_i<<std::endl;
    }
    void Print()
    {
        std::cout<<"Print() "<<_i<<std::endl;
    }
};

struct B
{
    std::shared_ptr<A> Asp;
    std::mutex AspMutex;

    void SetA()
    {
        static int i = 0;
        std::unique_lock<std::mutex> lock(AspMutex);
        Asp = std::make_shared<A>(i);
    }

    void AccessA1()
    {
        std::shared_ptr<A> aspCopy;
        {
            std::unique_lock<std::mutex> lock(AspMutex);
            aspCopy = Asp;
        }
        (*aspCopy).Print();
    }

    void AccessA2()
    {
        auto aspCopy = [&]()
        {
            std::unique_lock<std::mutex> lock(AspMutex);
            return Asp;
        }();
        (*aspCopy).Print();
    }

    void AccessA3()
    {
        (*[&]()
        {
            std::unique_lock<std::mutex> lock(AspMutex);
            return Asp;
        }()
        ).Print();
    }

};

int main()
{
    B b;
    b.SetA();
    std::thread t([&]{b.SetA();});
    b.AccessA1();
    b.AccessA2();
    b.AccessA3();
    t.join();
}

Мне любопытно, будет ли стандарт c ++ 17 (или более поздней версии) гарантировать, что методы A::Access1 и A::Access2 являются поточно-ориентированными (копия * 1006) * будет защищен lock).

1 Ответ

1 голос
/ 21 января 2020

Да. Блокировка делает A::Access1 и A::Access2 потокобезопасным с одновременным SetA. Это все еще верно в C ++ 17.

...