簡體   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