Вопрос об атомной спиновой блокировке и std :: this_thread :: yield () - PullRequest
0 голосов
/ 29 января 2019

Я пытался реализовать C ++ пул потоков с STL, который принимает задачи в очередях и отправляет задачи потокам для выполнения.Очередь использует атомную спин-блокировку при нажатии и выталкивании, и, кажется, все работает хорошо со следующим кодом:

void push(const std::function<bool()>& func){
    while(in_use.exchange(true, std::memory_order_acquire));
    //Actually push the queue, deal with possible exceptions, etc.
    in_use.store(false, std::memory_order_release);
}

std::function<bool()> pop(){
    while(in_use.exchange(true, std::memory_order_acquire));
    //Actually push the queue, deal with possible exceptions, etc.
    in_use.store(false, std::memory_order_release);
}
.....//other functions for determining size, etc.

Позже я решил, что std :: this_thread :: yield может быть хорошим выбором вцикл.

(Я включил свой компьютер, когда тестировал задачу, которая помещает ту же задачу в пул, а затем опрашивает пул, когда я устанавливаю приоритет выполнения процесса в режиме реального времени ...)

Однако, когда я изменил строку

while(in_use.exchange(true, std::memory_order_acquire));

на

while(in_use.exchange(true, std::memory_order_acquire)) std::this_thread::yield();

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

IМне было интересно, что именно функция yield может сделать для операции с атомарными переменными, которая может привести к этой проблеме.

PS: Аппаратное обеспечение процессора: Intel Core i5, ОС Windows 10 1803, VS 2017 SDK version 10.0.17763.0.

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