Почему очереди сообщений используются вместо многопоточности? - PullRequest
1 голос
/ 28 января 2011

У меня есть следующий запрос, который мне нужен, чтобы кто-нибудь помог мне с этим. Я новичок в очередях сообщений и недавно начал просматривать очередь сообщений Kestrel.Как я понимаю, и потоки, и очереди сообщений используются для параллелизма в приложениях, так в чем же преимущество использования очередей сообщений по сравнению с многопоточностью?

Пожалуйста, помогите Спасибо.

Ответы [ 4 ]

4 голосов
/ 28 января 2011

очереди сообщений позволяют вам общаться вне вашей программы.

Это позволяет вам отделить вашего производителя от вашего потребителя.Вы можете распределить выполняемую работу по нескольким процессам и машинам, а также можете управлять / обновлять / перемещать эти программы независимо друг от друга.

Очередь сообщений также обычно состоит из одного или нескольких посредников, которые позаботятся о них.распространения ваших сообщений и проверки того, что сообщения не будут потеряны в случае чего-то плохого (например, ваша программа аварийно завершает работу, вы обновляете одну из своих программ и т. д.)в этом случае это часто просто средство для обмена / очереди данных из потока производителя в поток потребителя для выполнения асинхронной обработки.

2 голосов
/ 28 января 2011

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

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

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

1 голос
/ 20 февраля 2013

Создание потоков стоит дорого, и каждый поток, который является одновременно «живым», будет добавлять определенное количество служебной информации, даже если поток заблокирован, ожидая, что что-то произойдет. Если у программы Foo есть 1000 задач, которые нужно выполнить, и на самом деле все равно, в каком порядке они выполняются, возможно, будет возможно создать 1000 потоков и каждый поток будет выполнять одну задачу, но такой подход не будет ужасно эффективным. Второй альтернативой было бы, чтобы один поток выполнял все 1000 задач последовательно. Если бы в системе были другие процессы, которые могли бы использовать какое-либо процессорное время, которое Foo не использовал, этот последний подход был бы эффективным (и вполне возможно оптимальным), но если не было достаточно работы, чтобы держать все процессоры занятыми, процессоры могли бы тратить время на бездействие. В большинстве случаев оставить процессор на секунду бездействующим так же дорого, как потратить секунду процессорного времени (главное исключение - попытка минимизировать потребление электроэнергии, поскольку на холостом ходу процессор может потреблять гораздо меньше энергии, чем занятый). ).

В большинстве случаев лучшая стратегия - это компромисс между этими двумя подходами: иметь некоторое количество потоков (скажем, 10), которые начинают выполнять первые десять задач. Каждый раз, когда поток завершает задачу, пусть он начинает работать с другой, пока все задачи не будут завершены. При таком подходе накладные расходы, связанные с многопоточностью, будут сокращены на 99%, и единственными дополнительными затратами будет очередь задач, которые еще не были запущены. Поскольку запись в очереди, как правило, намного дешевле, чем поток (вероятно, менее 1% от стоимости и, возможно, менее 0,01%), это может дать действительно огромную экономию.

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

1 голос
/ 28 января 2011

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

Короткий ответ заключается в том, что передача сообщений легче для мозга.Подробнее ...

Передача сообщений работает путем отправки сообщений от одного агента другому.Как правило, нет необходимости координировать доступ к данным.Как только агент получает сообщение, он обычно может предполагать, что у него есть неквалифицированный доступ к этим данным.

Стиль «многопоточность» работает, предоставляя всем агентам доступ с открытым доступом к общим данным, но требуя от них тщательной координации своего доступа.через примитивы.Если один агент ведет себя плохо, процесс становится поврежденным, и весь ад проваливается.Передача сообщений имеет тенденцию ограничивать проблемы неправильно работающим агентом и его когортой, и поскольку агенты, как правило, являются автономными и часто программируются в стиле последовательного или конечного автомата, они, как правило, ведут себя не так часто - или столь таинственно - как обычный многопоточный код.

...