Возможно ли несколько продюсера, однопонаправленного в настройке без блокировки?
Вопрос
У меня есть куча тем, которые много общаются друг с другом. Я бы предпочел, чтобы это было бесплатно.
Для каждого потока я хочу иметь почтовый ящик, где другие потоки могут отправлять ему сообщения (но только владелец может удалить сообщения). Это ситуация с одним потребителем с несколькими продуктами. Возможно ли я сделать это в блокировке / высокой производительности? (Это во внутренней петле гигантского симуляции.)
Решение
Конечно, если у вас есть атомный CompareAndSwap
Инструкция:
for (i = 0; ; i = (i + 1) % MAILBOX_SIZE)
{
if ((mailbox[i].owned == false) &&
(CompareAndSwap(&mailbox[i].owned, true, false) == false))
break;
}
mailbox[i].message = message;
mailbox[i].ready = true;
После прочтения сообщения, потребляющая потока просто устанавливается mailbox[i].ready = false; mailbox[i].owned = false;
(в этой последовательности).
Другие советы
Очередь с несколькими производителями (MPSC) без блокировки является одним из самых простых алгоритмов без блокировки для реализации.
Самая базовая реализация требует простого без блокировки. Функции доступны в API Windows как InterlockedFlushSlist () и InterlockedPushentrySlist (), но их очень легко катиться самостоятельно.
Многочисленные продукты push () push () на строительстве с использованием CAS (с блокировкой Compare-and-Swap).
Одиночный потребитель выполняет промывку (), который заменяет головку строк с нулем, используя XCHG (взаимосвязанный обмен). Затем потребитель имеет список предметов в обратном порядке.
Чтобы обработать элементы по порядку, вы должны просто отменить список, возвращенный из flush (), прежде чем обрабатывать его. Если вы не заботитесь о заказе, вы можете просто немедленно пройти список, чтобы обработать его.
Две заметки, если вы бросаете свои собственные функции:
1) Если вы находитесь в системе со слабым упорядочением памяти (т.е. PowerPC), вам необходимо поместить «барьер памяти» в начале функции push () и «барьер памяти акварея» в конце промывки ( ) функция.
2) Вы можете сделать функции значительно упрощенными и оптимизированными, поскольку во время функции POP () возникает ABA-выпуск. Вы не можете иметь ABA-Issues с жестяной, если вы используете только push () и flush (). Это означает, что вы можете реализовать его как единый указатель, очень похожий на код без беззакония, и нет необходимости в счетчике последовательности ABA.
Вот Бумага из Университета Рочестера, иллюстрирующая неблокирующую одновременную очередь. Анкет Алгоритм, описанный в бумаге, показывает одну технику для изготовления беззаконной очереди.
Возможно, захочет взглянуть на строительные блоки Intel Thread, я помню, что вы читали лекции по разработчику Intel, который упомянул кое -что в этом направлении.