如何使用互斥锁作为成员变量?没有' simple_encoder'的复制构造函数被隐式删除

时间:2018-03-26 20:53:02

标签: c++ mutex

您好我正在尝试创建一个需要互斥锁的多线程编码器,我希望该互斥锁成为该类的成员。但是,当我编译时,我不断收到:copy constructor of 'simple_encoder' is implicitly deleted because field 'm_mutex' has an inaccessible copy constructor作为错误消息。经过一个小时的搜索,我找不到我的错误。

请为某些东西的爱帮助我,我的构造函数和成员看起来像这样:

namespace master_thesis
{
class simple_encoder
{
public:

    simple_encoder(uint32_t symbols, uint32_t symbol_size, fifi::api::field field,
                   std::vector<uint8_t> data) :
        m_symbols(symbols), m_symbol_size(symbol_size),
        m_completed(0), m_field(field), m_data(data)
    {

    }
...
private:

    uint32_t m_symbols;
    uint32_t m_symbol_size;
    uint32_t m_completed; 

    fifi::api::field m_field;

    std::mutex m_mutex;

    std::vector<uint8_t> m_data;
    std::vector<std::vector<uint8_t>> m_result;

    std::vector<std::shared_ptr<kodo_rlnc::full_vector_encoder>> m_encoders;
};
}

2 个答案:

答案 0 :(得分:4)

要复制包含互斥锁的对象,您必须编写自定义复制构造函数复制赋值运算符

您不需要复制互斥锁来复制对象,因为互斥锁不是对象值<的一部分/ em>,它只是作为保护访问的工具。

复制时,两个对象的互斥锁需要用于在复制过程中保护值成员

例如:

class simple_encoder
{
public:

    simple_encoder() {}

    // copy constructor
    simple_encoder(simple_encoder const& other)
    {
        // no need to lock this objec because no other thread
        // will be using it until after construction
        // but we DO need to lock the other object
        std::unique_lock<std::mutex> lock_other(other.m_mutex);

        // safely copy the data
        m_symbols = other.m_symbols;
        m_symbol_size = other.m_symbol_size;
        m_completed = other.m_completed;

        // ... etc...
    }

    // copy assignment operator
    simple_encoder& operator=(simple_encoder const& other)
    {
        if(&other != this)
        {
            // lock both objects
            std::unique_lock<std::mutex> lock_this(m_mutex, std::defer_lock);
            std::unique_lock<std::mutex> lock_other(other.m_mutex, std::defer_lock);

            // ensure no deadlock
            std::lock(lock_this, lock_other);

            // safely copy the data
            m_symbols = other.m_symbols;
            m_symbol_size = other.m_symbol_size;
            m_completed = other.m_completed;

            // ... etc...
        }

        return *this;
    }

private:
    // value data
    uint32_t m_symbols;
    uint32_t m_symbol_size;
    uint32_t m_completed;

    // non value utility
    mutable std::mutex m_mutex; // needs to be mutable
};

也可以为移动对象编写类似的函数。

如果你有C++14,你可以使用std::shared_timed_mutex并在复制期间锁定其他对象时替换std::shared_lock<std::shared_timed_mutex>,这应该更有效。当移动时,您仍然需要std::unique_lock

答案 1 :(得分:1)

您的类可能包含互斥锁作为成员,但是您的类自动不可复制,因为互斥锁不可复制,并且互斥锁现在是您的类的一部分。

所以,无论你在哪里复制你的课程(用你没有给我们看过的代码),你根本就不能这样做了。

由于同样的原因,你的班级现在也不可移动。

如果这是一个问题,您可以将互斥锁隐藏在共享指针之后。但是我会担心共享指针的同步,所以尽量不要......