ОК, так что есть три действительные состояния:
Нет потоки не выполняющиеся функции в обеих группах.
Один или несколько потоков выполняются функции в группе А.
Один или несколько потоков стереосистеме и обновите функции в группе В.
Как и большинство сложных схем фиксирующих, это может управлять состоянием внутри замка. Состояние может быть перечислением, например (EgsFree, EgsAonly, EgsBonly), threadCount int, который отслеживает, сколько потоков любой из групп находится в защищенных функциях и контейнер для объектов синхронизации, по которым потоки, которые не были разрешены для запуска, ожидание.
Функции должны будут взаимодействовать, вызывая в заблокированное состояние при входе (идентифицируя свою группу с параметром) и при выходе.
Темы, которые обнаруживают при попытке ввода, что им не разрешено выполнять свою функцию, должны блокировать себя, поднимая событие/семафор, сохраняя его в контейнере и ожидая его после выхода из состояния блокировки. Это позволяет потокам, которые уменьшают счет до 0, (и поэтому снова устанавливают состояние в Efree), при выходе для итерации контейнера и подготовки всех ожидающих потоков.
Учитывая эту структуру, вы можете реализовать алгоритм против голодания или другие схемы управления, как вы пожелаете.
Данные состояния в замке грязные, и я хотел бы увидеть более простое решение этой проблемы. OTOH, он остается единственным безопасным способом комплексного управления ресурсами, о котором я знаю, на который можно положиться, чтобы работать и не иметь скрытого потенциала гонки/тупика. Если вам нужно слишком много думать о схеме блокировки, есть вероятность, что он в какой-то момент испортится :)
Какой язык вы используете - C или C++? Какую версию этого языка вы используете? На какой платформе или платформах вы работаете? Вы ищете код, используя средства, предоставляемые языковым стандартом, или вы ищете возможности, предоставляемые хостом O/S? И, в общем, почему вы считаете, что мьютекс не подходит? Один мьютекс может использоваться для защиты как набора A, так и множества B-функций; вы должны захватить этот мьютекс перед вызовом любой из подпрограмм в любом наборе. Конечно, это уменьшает параллелизм, но это кажется приемлемым. –
@JonathanLeffler У меня есть полный доступ к потокам posix. Я пытаюсь найти способ свести к минимуму блокировку. – xiver77
Просто, чтобы быть ясным - может быть 200 потоков, вызывающих функцию в группе A, до тех пор, пока нить не будет в функции в группе B, да? –