Гарантируют ли спин-блокировки переключение контекста по сравнению с мьютексами? - PullRequest
1 голос
/ 26 февраля 2020

Рассмотрим следующий фрагмент кода

int index = 0;
av::utils::Lock lock(av::utils::Lock::EStrategy::eMutex); // Uses a mutex or a spin lock based on specified strategy.

void fun()
{
    for (int i = 0; i < 100; ++i)
    {
        lock.aquire();
        ++index;
        std::cout << "thread "  << std::this_thread::get_id() << " index = " << index << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        lock.release();
    }
}

int main()
{
    std::thread t1(fun);
    std::thread t2(fun);

    t1.join();
    t2.join();
}

Вывод, который я получаю с мьютексом, используемым для синхронизации, заключается в том, что первый поток 1 полностью выполняется, а затем поток 2. При использовании спин-блокировки (реализованной с использованием std :: atomic_flag), я получаю порядок выполнения между потоками, которые чередуются (одна итерация потока 1, затем другая итерация потока 2). Последний случай происходит независимо от задержки, которую я добавляю при выполнении итерации.

Я понимаю, что мьютекс гарантирует только взаимное исключение, а не порядок выполнения. У меня такой вопрос: хочу ли я иметь порядок выполнения таким образом, чтобы два потока выполнялись с чередованием, использование спин-блокировки рекомендуемой стратегии или нет?

1 Ответ

1 голос
/ 26 февраля 2020

Вывод, который я получаю с мьютексом ... это первый поток 1 [проходит через весь цикл], а затем поток 2.

Это из-за того, как ваш l oop использует блокировку: самое последнее, что делает тело l oop, это разблокирует блокировку. Следующее, что он делает в начале следующей итерации, это снова блокирует блокировку.

Другой поток может быть заблокирован, фактически находясь в спящем режиме, ожидая мьютекс. Когда ваш поток 1 снимает блокировку, планировщик ОС все еще может запускать свои алгоритмы, пытаясь выяснить, как на это реагировать, когда поток 1 возвращается и снова блокирует блокировку.

Это похоже на гонку чтобы заблокировать мьютекс, и нить 1 находится на стартовой линии, когда пистолет гаснет, а нить 2 сидит на скамейке, связывая свои туфли.

При использовании спин-блокировки ... порядок выполнения между потоками, которые чередуются

Это потому, что «заблокированный» поток действительно не заблокирован. Он все еще активно работает на другом процессоре, пока ждет. У него гораздо больше шансов выиграть блокировку, когда ее освободит первый поток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...