繁体   English   中英

使用 std::lock_guard 数组锁定 std::mutex 数组

[英]Locking an array of std::mutex using a std::lock_guard array

我有以下互斥体数组:

std::mutex mtx[5];

我想用 RAII 风格锁定它们:

std::lock_guard<std::mutex> grd[5] { mtx[0], mtx[1], mtx[2], mtx[3], mtx[4] };

虽然上面的代码有效,但它并不理想,因为我不能独立于数组的大小(这里是 5)编写它。

有没有办法做到这一点? 我应该使用模板魔法从数组中创建一个std::initializer_list吗? (那可能吗?)

我愿意使用std::arraystd::vector代替 C 风格的 arrays,我在这里使用它们是为了简洁。 理想情况下,这适用于 C++14,但任何符合最新标准的解决方案都可以。

你想要的是std::scoped_lock 它需要 N 个互斥体并在创建时锁定它们并在销毁时解锁。 那会给你

std::scoped_lock sl{mtx[0], mtx[1], mtx[2], mtx[3], mtx[4]};

如果这仍然太冗长,您可以将其包装在工厂 function 中,例如

// function that actually creates the lock
template<typename Mutexes, std::size_t N, std::size_t... Is>
auto make_scoped_lock(Mutexes (&mutexes)[N], std::index_sequence<Is...>)
{
    return std::scoped_lock{mutexes[Is]...};
}

// helper function so you don't have to create your own index_sequence
template<typename Mutexes, std::size_t N>
auto make_scoped_lock(Mutexes (&mutexes)[N])
{
    return make_scoped_lock(mutexes, std::make_index_sequence<N>{});
}

int main()
{
    std::mutex mtx[5];
    auto lock = make_scoped_lock(mtx);
}

如果您切换到使用std::array来保存互斥体,那么代码可以简化为对std::apply的调用以将数组扩展为参数包,例如

template<typename Mutexes>
auto make_scoped_lock(Mutexes& mutexes)
{
    return std::apply([](auto&... mutexes) { return std::scoped_lock{mutexes...}; }, 
                      mutexes);
}

int main()
{
    std::array<std::mutex, 5> mtx;
    auto sl = make_scoped_lock(mtx);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM