Ради изучения комбинаторики boost::thread я реализую простой барьер (BR) для потоков, которые блокируют общий мьютекс (M). Однако, насколько я понимаю, при переходе к BR.wait() блокировки на мьютексе не снимаются, поэтому для того, чтобы все потоки достигли BR, необходимо выполнить ручное снятие блокировки на M. Итак, у меня есть следующий код:
boost::barrier BR(3);
boost::mutex M;
void THfoo(int m){
cout<<"TH"<<m<<" started and attempts locking M\n";
boost::lock_guard<boost::mutex> ownlock(M);
cout<<"TH"<<m<<" locked mutex\n";
Wait_(15); //simple wait for few milliseconds
M.unlock(); //probably bad idea
//boost::lock_guard<boost::mutex> ~ownlock(M);
// this TH needs to unlock the mutex before going to barrier BR
cout<<"TH"<<m<<" unlocked mutex\n";
cout<<"TH"<<m<<" going to BR\n";
BR.wait();
cout<<"TH"<<m<<" let loose from BR\n";
}
int main()
{
boost::thread TH1(THfoo,1);
boost::thread TH2(THfoo,2);
boost::thread TH3(THfoo,3);
TH2.join(); //but TH2 might end before TH1, and so destroy BR and M
cout<<"exiting main TH \n";
return 0;
}
Принимая во внимание, что M.unlock() явно плохое решение (без использования блокировки); так как (просто) снять блокировку? Также: как мне (правильно) ждать в main() завершения всех потоков? (TH2.join() не работает, потому что TH2 может завершиться первым...);
Пожалуйста, не предлагайте уход на второй круг, т.е. с условными переменными, которые я тоже могу использовать, но должна быть возможность сделать это прямо без них.