Если мы используем notify_one () для пробуждения потока, нам все еще нужен yield () - в C ++? - PullRequest
0 голосов
/ 28 сентября 2018

доход (): https://en.cppreference.com/w/cpp/thread/yield
notify_one (): http://www.cplusplus.com/reference/condition_variable/condition_variable/notify_one/

Случай:

Предполагается, что поток A завершит все, что он делает, и затем вызовет поток B для выполнения своей работы.

Я написал вызов notify_one () в функции A 'run () потока'.

Возможен ли случай, когда поток A сигнализирует notify_one (), но поток A все еще запланирован, даже если поток B готов?

Являются ли notify_one () и yield () эквивалентными друг другу

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

yield и notify_one не связаны между собой.

yield - это запрос процесса (к ОС) об отказе от текущего временного интервала.Тема все еще будет запланирована в следующий раз.Представьте, что процессу выделяется 10 мс.Если он вызывает yield через 5 мс, ОС может запустить другой процесс.В следующий раз он по-прежнему получает полные 10 мсек.ОС не должна выполнять запрос.

condition_variable::notify_one используется вместе с condition_variable::wait.Если есть какие-либо ожидающие потоки, notify_one гарантированно разбудит один из них.Если нет ожидающих потоков, notify_one ничего не сделает.

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

Возможен ли случай, когда поток A сигнализирует notify_one (), но все же поток A снова запланирован, даже если поток B готов?

Да.С семантикой Mesa, сигнализация ожидающего потока просто разблокирует другой поток.Текущий поток может продолжать работать, пока не истечет время.При семантике Hoare сигнальный поток немедленно переключается на ожидающий поток.Однако почти во всех реализациях условий используется семантика Mesa.

Являются ли notify_one () и yield () эквивалентными друг другу?

"Эквивалент" будет означать, что онисделать то же самое.Это не относится к делу.Я думаю, что вы хотите спросить, являются ли они бесплатными, или они являются частью той же схемы синхронизации, и ответ - нет, как я объяснил выше.

Если мы используем notify_one(), чтобы разбудитьнам нужен поток yield()

Если нить A только что разбудила нить C с nofity_one и вы хотите запустить нить C как можно скорее, вы можете позвонить yield, чтобы получитьдо остальной части времени нити А.Однако ОС не обязана удовлетворять ваш запрос.И может быть много потоков, запланированных перед тем C, которые вы не можете контролировать.

0 голосов
/ 28 сентября 2018

Есть разница между обоими.Есть вероятность, что в вашем случае вы можете использовать любой из них с одинаковым эффектом.yield является более общим, а notify_one обеспечивает больший контроль над потоком программы.

yield: освободить процессор, чтобы ОС могла запланировать любой другой поток .
notify_one: сигнализировать условие, чтобы один из потоков, ожидающих этого условия, мог возобновить работу.

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

notify_one - правильный выбор, когда один поток ожидает условия, а другой может сигнализировать об этом.

...