LINUX.ORG.RU

Аналог futex в OS Mac/BSD

 ,


0

3

Привет Всемогущий All.

Есть задача производитель/потребитель в многопоточном режиме (один поток производитель, другой потребитель) с lockfree очередью. Нужно сделать, чтобы потребитель мог отправиться спать при отсутствии задач в очереди, а производитель мог его разбудить, когда появились новые задачи и хоть один потребитель спит (тех и других может быть по несколько потоков). Очередь lockfree, поэтому в нагруженном режиме (в очереди есть задачи, все потребители работают) все должно работать без блокировок. Условные переменные не подходят, т.к. notify() из производителя хоть и можно делать без блокировки, но он легко может вклиниться между проверкой потребителем очереди и засыпанием...

В Linux есть замечательное средство - FUTEX(2) (сколько бы в его man'е не пугали, что его осилит только избранный, в реальности все довольно просто с атомарными переменными), даже в Windows(8/2012) есть WaitOnAddress (правда со своими особенностями). Библиотеку хочется сделать кроссплатформенной, поэтому осталось определиться с третьей Os, которая имеет хоть какое-то значение для релизации - Mac (BSD).

Суть реализации в Linux (и Windows) в том, что поток заснет только при условии, что переменная (int) выставлена в определенное значение, поэтому для notify() нужно изменить ее значение на «не спать», после этого никто не уснет, и сделать FUTEX_WAKE, чтобы кто-нибудь проснулся (возможно, проснется один + кто-то не заснет, но хоть один, все же проснется). В результате засыпание/пробуждение получается сделать без гонок и блокировок (отсутствие блокировок важно только в нагруженном режиме, т.к. если начались засыпания, то потокам нечего делать и дополнительные расходы значения не имеют - потоки и так бездельничают).

Вопрос, какой есть аналог Futex в ядре BSD (кроме эмуляции Linux) для реализации такой задачи?

Ответ на: комментарий от anonymous

Спасибо, похоже, то что надо. Осталось понять, есть ли оно на маке и как это на нем использовать.

chimera19
() автор топика

Библиотеку хочется сделать кроссплатформенной, поэтому...

... всё равно придётся делать фолбек на mutex + condvar.

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

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

mashina ★★★★★
()

Обычно если хотят без блокировок, делают на атомарных переменных. Чем не устраивает такой подход?

UPD. Вообще сейчас pthreads и переключение контекста весьма быстры. Стоит ли огород городить?

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

Обычно если хотят без блокировок, делают на атомарных переменных. Чем не устраивает такой подход?

Я именно это и делаю. Только мне еще нужно реализовать засыпание потока, которому нечем заняться.

UPD. Вообще сейчас pthreads и переключение контекста весьма быстры. Стоит ли огород городить?

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

chimera19
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.