it is necessary to block N motehov but I don't want to write Tokyo code.

std::lock(arr[0], arr[1], ...., arr[N-1]); 

If you run over all mutexes and call lock ()

 for(auto& mtx : arr) { mtx.lock(); } 

this can lead to deadlocks.

  • 2
    And why do you need so many mutexes? Maybe you can make it easier? - trollingchar
  • Create another mutex root. - AlexGlebe
  • let's say it eats 16 streams, each of them has its own data but in some cases that do not occur, they do not start using each other's data, in these branches it is necessary to block everything, but when the stream uses its data it is necessary to block only one mutex. - Argishty Ayvazyan
  • So standard std :: lock is so able out of the box. - KoVadim 8:36 pm

2 answers 2

 namespace details { template<typename T, size_t N, size_t ... Indexes> void lock_all_impl(std::array<T, N> & muts, std::index_sequence<Indexes...>) { std::lock(muts[Indexes]...); } }//end of namespace details template<typename T, size_t N> void lock_all(std::array<T, N> & muts) { details::lock_all_impl(muts, std::make_index_sequence<N>()); } //использование: std::array<std::mutex, mutex_count> arr; lock_all(arr); 
     mutex mutboss; array<mutex> arrmut; condition_variable sigboss; bool flagwaitsignal = false ; size_t guest_count = 0; mutex mutguests; void GlobalLock(){ mutboss.lock(); unique_lock<std::mutex> lock(mutguests); while(guest_count) { flagwaitsignal = true ; sigboss.wait(lock); } } void GlobalUnLock(){ mutboss.unlock(); } void PassIn(size_t ind){ mutboss.lock(); mutguests.lock(); ++guest_count; mutguests.unlock(); mutboss.unlock(); arrmut[ind].lock(); } void PassOut(size_t ind){ arrmut[ind].unlock(); mutguests.lock(); --guest_count; if(flagwaitsignal and guest_count == 0) { flagwaitsignal = false; sigboss.notify_one(); } mutguests.unlock(); } 

    Everything is written on the члаз - the syntax may be wrong, but this is a classic implementation, all in memory.