Я немного учу себя параллельному программированию, особенно с использованием мьютексов и потоков в C ++. Я написал следующий небольшой пример:
#include <iostream>
#include <thread>
#include <mutex>
// #include <chrono>
std::mutex M1,M2;
void task_one () {
std::cout << "AAAA!\n";
M1.lock();
// std::cout << "M1 locked in A\n";
M2.lock();
// std::cout << "M2 locked in A\n";
std::cout << "BBBB!\n";
M2.unlock();
// std::cout << "M2 unlocked in A\n";
M1.unlock();
// std::cout << "M2 unlocked in A\n";
}
void task_two () {
std::cout << "CCCC!\n";
M2.lock();
// std::cout << "M2 locked in B\n";
M1.lock();
// std::cout << "M1 locked in B\n";
std::cout << "DDDD!\n";
// M1.unlock();
// std::cout << "M1 unlocked in B\n";
M2.unlock();
// std::cout << "M2 unlocked in B\n";
}
int main () {
std::thread th1 (task_one);
std::thread th2 (task_two);
th1.join();
th2.join();
// th1.detach();
// th2.detach();
// std::chrono::milliseconds timespan(10);
// std::this_thread::sleep_for(timespan);
return 0;
}
Я ожидал, что этот код напечатает
AAAA!
CCCC!
, а затем заблокируется, когда task_one
попытается получить блокировку на M2 (потому что task_two
уже получит этот замок). Однако он печатает
AAAA!
BBBB!
CCCC!
DDDD!
Почему нет тупика? Кроме того, является ли это примером состояния гонки или этот код является поточно-ориентированным? Я думаю, что существует состояние гонки, потому что, если task_one
может получить блокировку на M2 до того, как task_two
сможет, тогда все будет выполнено (то есть task_one
завершит sh, а затем позволит task_two
начать) . Однако я запускал это несколько раз с теми же результатами. Кроме того, если мое словоблудие в отношении блокировок и потоков неверно, пожалуйста, поправьте меня.