Rozważmy prosty przykład zbieżność:Zamówienie wątków w wykonaniu
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
std::mutex mtx; // mutex for critical section
void print_block(int n, char c) {
// critical section (exclusive access to std::cout signaled by locking mtx):
mtx.lock();
for (int i = 0; i<n; ++i) { std::cout << c; }
std::cout << '\n';
mtx.unlock();
}
int main()
{
std::thread th1(print_block, 50, '*');
std::thread th2(print_block, 50, '$');
th1.join();
th2.join();
return 0;
}
Czy zawsze gwarantowane że th1
będzie pierwszy wątek do wykonania pętli for?
znaczenie, kiedy to zrobić:
th1.join();
th2.join();
Wtedy możemy być absolutnie pewni, że th1
będzie pierwszy, a następnie th2
stracony?
When zajmowanie się programowaniem współbieżnym, nigdy nie wysuwaj żadnej hipotezy o kolejności wykonywania. Przeciwnie, zakładaj, że wszystkie sytuacje są możliwe. Dzięki temu Twój kod jest bardziej niezawodny i paradoksalnie prostszy. –
[Używasz 'std :: mutex' wrong] (http://kayari.org/cxx/antipatterns.html#locking-mutex), nie powinieneś nigdy wywoływać' std :: mutex :: lock() 'i 'std :: mutex :: unlock()'. Zamiast tego stwórz 'std :: lock_guard' na początku 'print_block()' i pozwól mu zablokować i odblokować muteks dla ciebie. –