Pthread-Win32 Расширение SEM_POST_Multiple
-
30-09-2019 - |
Вопрос
В настоящее время я строю тонкую обертку C ++ вокруг Pthreads для внутреннего использования. Windows, а также QNX нацелены и к счастью, порты Pthreads-Win32, кажется, очень хорошо работают, а QNX соответствует Posix для наших практических целей.
Теперь при выполнении семафоров я попал в функцию
sem_post_multiple(sem_t*, int)
Что, по-видимому, доступно только на Pthreads-Win32, но отсутствует в QNX. Поскольку имя предполагает, что функция должна увеличивать семафор с помощью подсчета в качестве второго аргумента. Насколько я могу сказать, функция не является частью ни POSIX 1B, ни POSIX 1C.
Хотя в настоящее время нет никаких требований к указанной функции, мне все еще интересуется, почему pthreads-win32 предоставляет функцию и может ли она использовать. Я мог бы попытаться имитировать его для QNX, используя аналогичное следующее:
sem_post_multiple_qnx(sem_t* sem, int count)
{
for(;count > 0; --count)
{
sem_post(sem);
}
}
То, что я прошу, это предложение / совет о том, как продолжить. Если консенсус предлагает выполнить реализацию функции для QNX, я бы также оценил комментарии о том, является ли предложенным кодом, является жизнеспособным решением.
Заранее спасибо.
PS: Я намеренно покинул свой нравственный класс C ++ для ясности. Для всех людей, предлагающих повышение к спасению: это не вариант в моем текущем проекте из-за причин управления.
Решение
В любом случае семафоры являются дополнительным расширением в POSIX. Например, OS X, похоже, не выполняет их полностью. Поэтому, если вы обеспокоены переносимостью, вам придется предоставлять обертки функциональных возможностей, которые вам нужны, в любом случае.
Ваш подход к эмулированию атомного приращения sem_post
имеет определенно нисходящие.
- Это может быть плохо выступать, где обычно
sem_t
используются в эффективности критических контекстов. - Эта операция не будет атомной. Настолько запутанные вещи могут произойти, прежде чем закончить петлю.
Я бы придерживался только необходимой, строго Posix соответствующий. Остерегайтесь sem_timedwait
Еще одна необязательная часть опции семафор.
Другие советы
Ваше предложенное реализация sem_post_multiple
не играет хорошо с sem_getvalue
, поскольку sem_post_multiple
является атомным увеличением, и поэтому для «одновременного» вызова невозможно sem_getvalue
Чтобы вернуть любой из промежуточных значений.
Лично я хотел бы оставить их обоих: пытаясь добавить фундаментальные операции синхронизации в систему, которая не хватает их игры, и ваша оболочка может скоро перестать быть «тонким». Так что не попадайте в него, если у вас нет кода, который использует sem_post_multiple
, что вы абсолютно должны портировать.
SEM_POST_MultiPle () - это нестандартная функция помощника, представленная сопровождающими Win32-Pthreads. Ваша реализация не такая же, как их, потому что многие уменьшения не являются атомными. То есть ли это проблема зависит от предполагаемого использования. (Лично я бы не пытался осуществить эту функцию, если / до тех пор, пока не возникает.)
Это интересный вопрос. +1.
Я согласен с текущим преобладающим консенсусом, что, вероятно, не очень хорошая идея для реализации этой функции. Хотя ваша предлагаемая реализация, вероятно, будет работать просто в большинстве ситуаций, существуют определенно условия, в которых результаты могут быть резко отличаться в связи с невыразимой. Ниже придумывается одна (чрезвычайно) надуманная ситуация:
- Запустите резьбу A, который вызывает sem_post_multiple (s, 10)
- Тема B ждет ждать s выпускается. Тема B убивает нить A.
В приведенном выше недружественном сценарии атомная версия увеличила бы семафор на 10. С не атомной версией он может быть только один раз. Этот пример, безусловно, вполне вероятно, в реальном мире. Например, убийство нити почти всегда плохо не говоря уже о том, что он может оставить объект семафора в неверном состоянии. Реализация Win32 может оставить блокировку Mutex на семафоре - увидеть это за то, почему.