Лучше заблокировать общий ресурс или иметь поток для выполнения запросов?

У меня есть общий пул памяти, из которого многие разные потоки могут запрашивать выделение. Запрос выделения из этого будет происходить МНОГО в каждом потоке, однако количество потоков, вероятно, будет небольшим, часто с запущенным только 1 потоком. Я не уверен, какой из следующих способов справиться с этим лучше.

В конечном счете, мне, возможно, придется реализовать оба и посмотреть, что дает более благоприятные результаты... Я также боюсь, что даже мысль о № 2 может быть преждевременной оптимизацией на данном этапе, поскольку на самом деле у меня еще нет кода, который использует этот общий ресурс. написанный. Но проблема настолько чертовски интересна, что продолжает отвлекать меня от другой работы.

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

2) Пусть каждый поток регистрирует слот запроса, когда ему требуется выделение, он помещает запрос в слот, а затем блокирует (пока (результат == NULL) { usleep() }), ожидая, пока слот запроса будет иметь результат. Один поток непрерывно повторяет слоты запросов, делая распределения и присваивая их результату в слоте запроса.

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

ПРИМЕЧАНИЕ. C в Linux с использованием pthreads


person Exodist    schedule 07.08.2011    source источник
comment
В вашем решении № 2, как вы обеспечиваете атомарный доступ к результату? А справочная страница для usleep() (которая принимает аргумент, кстати) говорит, что она приостанавливает вызывающий процесс.   -  person Keith Thompson    schedule 08.08.2011
comment
Страница руководства неверна; это просто написано кем-то, кто не знал или был огорчен тем, что темы существуют. Правильная документация для usleep находится здесь: pubs.opengroup.org/onlinepubs/009695399/ functions/usleep.html   -  person R.. GitHub STOP HELPING ICE    schedule 08.08.2011
comment
@R .. Старые справочные страницы Linux (такие как linux.die) в этом отношении неверны.   -  person cnicutar    schedule 08.08.2011
comment
Кстати, обратите внимание, что usleep был удален из POSIX в последней редакции, а в предыдущей версии он уже был помечен как устаревший. Вместо этого для современных приложений следует использовать nanosleep.   -  person R.. GitHub STOP HELPING ICE    schedule 08.08.2011


Ответы (1)


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

Я бы посоветовал использовать решение 1, но я немного скептически отношусь к тому факту, что вы для начала упомянули «пул памяти». Вы просто пытаетесь выделить память или есть какой-то другой ресурс, которым вы управляете (например, слоты в каком-то особом типе памяти, файл с отображением памяти, текстуры в видеопамяти и т. д.)?

Если вы просто выделяете память, то вы совершенно правы, беспокоясь о преждевременной оптимизации. Вся проблема заключается в преждевременной оптимизации, и система malloc будет работать не хуже или даже лучше, чем ваш пул памяти. (Или, если ваш код будет работать на одной из немногих систем с патологически неработающим malloc, например, на некоторых игровых приставках, просто добавьте замену только на те известные неисправные системы.)

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

person R.. GitHub STOP HELPING ICE    schedule 07.08.2011