LINUX.ORG.RU

Очередь перед мьютексом

 ,


0

2

Когда треды собираются перед mutex'ом,

std::lock_guard<std::mutex> lock(mutex);

они пробуждаются в той же последовательности, в которой пришли? То есть там образуется внутренняя очередь (thread-safe queue)? Или же в рандомном порядке?

Не знаю, влияет ли на это ЯП или это зависит от ОС. Поясните, пожалуйста, кто в курсе.


Не знаю, влияет ли на это ЯП или это зависит от ОС.

совершенно очевидно, что поведение зависит от конкретной реализации

std::lock_guard std::mutex

вот в этот самый std::lock_guard и std::mutex и надо смотреть

FishHook
()
Последнее исправление: FishHook (всего исправлений: 1)
Ответ на: комментарий от spbzip

Это детали реализации. Нужно смотреть в стандарт c++ на предмет гарантий. Я не видел, чтобы порядок пробуждения был гарантирован стандартом. Значит правильный ответ: порядок пробуждения не определён.

ox55ff ★★★★★
()

о общем случае порядок не специфицирован. ты не должен полагаться на порядок.

теоретически порядок может существовать по приоритетам тредов. и то, полагаться не стоит.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от utf8nowhere

Можно подробнее?

допустим так

namespace
{
    std::mutex lock;
    std::condition_variable cv;
    std::thread_id thid;
    std::atomic<bool> shutdown{false};

    void threadWait(void)
    {
        std::unique_lock<std::mutex> lk(lock);
        cv.wait(lk, [&] { return std::this_thread::get_id() == thid || shutdown; });
    }

    void threadAllow(const std::thread_id & id)
    {
        std::lock_guard<std::mutex> lk(lock);
        thid = id;
        cv.notify_all();
    }
}
anonymous2 ★★★★★
()
Последнее исправление: anonymous2 (всего исправлений: 2)
Ответ на: комментарий от utf8nowhere

Буквами. Пишешь: кто первый встал на ожидание, того и тапки тот первым и просыпается. А потом разработчики реализации языка ломают голову как это обеспечить и какой ценой.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

угу, там еще вопрос - а если низкоприритетный тред встал первым, а высокоприоритетный - вторым, кто первый получит мьютекс.

если первым получает низкоприоритетный, то он блокирует высокоприоритетный, что противоречит принципу приоритетности.

alysnix ★★★
()
Ответ на: комментарий от utf8nowhere

В терминах абстрактной машины.

Не знаком с терминами абстрактной машины цпп. Но если смогли описать многопоточную модель памяти, с мьютексами и атомарными переменными, то и порядок потоков определят.

В любом случае, если комитет цпп выбрал способ описания языка через абстрактную машину, то это их проблема. Надо было придумывать что-то более гибкое, чтобы потом не испытывать трудности с описанием.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

Поможет. Если порядок определён стандартом, то рантайм языка должен будет это обеспечивать даже если ОС не поддерживает.

Мне даже интересно стало - и как Вы выкручиваться будете если ядро этого не гарантирует?

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Я никак не буду выкручиваться. Выкручиваться будут авторы реализации языка, если стандарт поставит их в это положение.

ox55ff ★★★★★
()
Последнее исправление: ox55ff (всего исправлений: 1)
Ответ на: комментарий от alysnix

Разница в том, что ты пишешь про детали реализации, а я про гарантии в стандарте. Поэтому если цпп не знает ничего про приоритеты, то даже если омега потоки начнут задвигать альфачей, то с т.з. языка никакого неправильного поведения нет.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

Выкручиваться будут авторы реализации языка, если стандарт поставит их в это положение.

К счастью - в комитете не полные отморозки сидят. А ещё есть такая вещь как «implementers veto», когда разработчики компиляторов говорят «да идите вы в сад со своими фантазиями», и оно использовалось больше одного раза.

bugfixer ★★★★★
()
Ответ на: комментарий от no-such-file

Это сильное требование, которое в большинстве случаев не нужно. А если всё таки понадобилась, то можно слепить из стандартных примитивов синхронизации. Я бы не добавлял это даже если ОС из коробки бесплатно давала такие гарантии.

ox55ff ★★★★★
()
Ответ на: комментарий от alysnix

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

Если работоспособность кода зависит от приоритета потоков, то с большой вероятностью он будет разваливаться под высокой нагрузкой или если его запустить не на компе разработчика.

ox55ff ★★★★★
()
Последнее исправление: ox55ff (всего исправлений: 1)
Ответ на: комментарий от bugfixer

Поможет. Если порядок определён стандартом, то рантайм языка должен будет это обеспечивать даже если ОС не поддерживает.

Мне даже интересно стало - и как Вы выкручиваться будете если ядро этого не гарантирует?

Сделать очередь тредов под капотом, как засыпают, пихать их id (или еще какой поинтер) в очередь, как просыпаются, сравнивать с началом очереди. Если не совпало, засыпать опять или как-то оптимизировать процесс, яхз, я дебил, но по-моему это очевидно.

untitl3d
()
Ответ на: комментарий от untitl3d

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

Эффективность зашкаливает. И что вообще гарантирует что Ваш «head» в обозримом будущем проснётся? Может у него относительный приоритет близок к нулю?

bugfixer ★★★★★
()
Ответ на: комментарий от ox55ff

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

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

alysnix ★★★
()
Ответ на: комментарий от bugfixer

Я не понимаю, почему тут говорят про приоритет. Обычно ко мьютексу подходят *одинаковые* потоки, воркеры, которые делают одну и ту же работу распараллелено. И приоритет у них одинаковый +/-. Всякие там джиттеры и ttl треда не так уж и важны здесь, если это не хай лоад, но я так же не понимаю зачем писать вообще хайлоад програмно, когда можно электрическими импульсами работать =\

untitl3d
()
Ответ на: комментарий от alysnix

А для каких задач приоритеты могут понадобится? Обычно это костыли вида «рррряяяя, окошки тормозят при перетаскивании, давайте повысим приоритет композитору». Очевидно, что это костыль.

ox55ff ★★★★★
()
Ответ на: комментарий от untitl3d

Я не понимаю, почему тут говорят про приоритет.

Хорошо, пусть они даже все с одинаковым приоритетом. Допустим, так случилось что у вас в queue на mutex 1000 потоков сидят. Какова вероятность что следующим проснётся «нужный»? И сколько времени пройдёт прежде чем он таки проснётся? Вот и я о том же.

bugfixer ★★★★★
()
Ответ на: комментарий от untitl3d

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

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

Я говорю про кривизну архитектуры клиентских приложений, а не библиотек потоков.

Считаю, что если приложение для своей нормальной работы требует шаманить приоритеты потоков, то это повод пересмотреть архитектуру, чтобы убрать это требование.

Но я открыт к контраргументации. Если приведёшь пример, где иначе никак нельзя, то я признаю, что приоритеты это няша.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

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

архитектура с вводом-выводом на внешние устройства тоже кривая, потому что ее делают высокоприоритетные треды. которые например гребут данные полученные по прерываниям.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

фоновой сборкой мусора

Ты про сборщик мусора в языках программирования? Так там обычно все потоки тормозятся на время работы сборщика. Низкий приоритет тут скорее вреден.

Если это что-то другое, то низкий приоритет может привести к тому, что сборщик не будет успевать убирать и наступит жопа, которую придётся подпирать следующим по счёту костылём. Выглядит как-то не очень.

которые например гребут данные полученные по прерываниям.

Прерывания это системные штуки. Тут приоритеты нужны. Я писал про клиентское ПО.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

Ты про сборщик мусора в языках программирования? Так там обычно все потоки тормозятся на время работы сборщика. Низкий приоритет тут скорее вреден.

читать тут https://learn.microsoft.com/ru-ru/dotnet/standard/garbage-collection/background-gc

alysnix ★★★
()
Ответ на: комментарий от spbzip

Пока по тестам они пробуждаются так же как приходят в 100% случаев.

На такое нельзя закладываться даже если в тестах повторяется. Если только в документации к Qthread не указано явно.

aiqu6Ait ★★★★
()
Ответ на: комментарий от alysnix

Там ничего про то с каким приоритетом выполняется фоновый поток сборщика мусора. Копаться в исходниках clr и искать с каким приоритетом запущен этот поток у меня нет желания.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

цитато:

...
В этом случае фоновая сборка мусора приостанавливается, чтобы позволить выполниться высокоприоритетной сборке мусора. После выполнения высокоприоритетной сборки мусора работа выделенного потока фоновой сборки мусора и пользовательских потоков возобновляется.
...

то есть есть фоновая и высокоприоритетная сборка. и они выполняются когда надо или позволяют условия… вообще полно в мире всяких фоновых задач и кроме сборки.

alysnix ★★★
()