Может ли один поток общаться с другим? - PullRequest
2 голосов
/ 05 февраля 2012

Есть ли в C # способ отправить сообщение другому потоку на основе идентификатора или имени потока?

По сути, для школьного проекта мой профессор хочет, чтобы мы заключили сделку с производителем / потребителем, но передаем объекты, сериализованные в строку (например, xml), от производителя к потребителю. Как только строка извлекается из буфера в потоке потребителя, каждая из этих строк декодируется (включая нить) и обрабатывается, а исходный производитель уведомляется посредством обратного вызова. Так как же отправить событие в исходный поток производителя только с идентификатором потока?

Ответы [ 4 ]

1 голос
/ 05 февраля 2012

Представьте, что вы управляете компанией, и вы можете нанять столько сотрудников, сколько захотите, но каждый сотрудник действительно целеустремлен, поэтому вы можете дать им только один заказ когда-либо . Вы не могли сделать много с ними, верно? Поэтому, если бы вы были умным менеджером, вы бы сказали: «Ваш заказ:« подождите в своей папке входящих сообщений, пока не получите письмо с указанием, что делать, выполните работу, а затем повторите »». Затем вы можете помещать рабочие элементы в почтовые ящики работника по мере необходимости.

Проблема в том, что случится, если вы дадите сотруднику долгосрочное, низкоприоритетное задание (скажем, «поехать в Топику, чтобы забрать арахисовое масло для пикника компании»). Сотрудник с радостью уйдет и сделает это. Но затем здание загорается, и вам нужно знать, что, если вы отдадите приказ, «возьмите огнетушитель и потушите огонь!» кто-то собирается сделать это быстро. Вы можете решить эту проблему, если несколько сотрудников будут использовать один и тот же почтовый ящик - таким образом, существует большая вероятность того, что кто-то будет готов выполнить приказ, чтобы потушить пламя, а не отправиться через Канзас.

Угадай что? Нитки те трудные сотрудники.

Вы не "передаете сообщения в ветку". Что вы можете сделать, это настроить поток или группу потоков для наблюдения за общей, общей структурой данных, такой как очередь блокировки (например, BlockingCollection в .NET), а затем помещать сообщения (например, ваши строки). ) в эту очередь для обработки потоками потребителя (которые должны прослушивать очередь для работы).

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

Наконец, вам нужна правильная синхронизация потоков (блокировка) в очередях, если она не встроена в очередь Producer / Consumer, с которой вы работаете. Представьте, что вы помещаете сообщение в папку «Входящие» работника, и этот работник так хотел прочитать сообщение, что взял его из вашей руки и разорвал пополам. Что вам нужно, так это возможность запретить доступ к очереди более чем одному потоку одновременно.

1 голос
/ 05 февраля 2012

При использовании потоков вы не пытаетесь отправлять сообщения между ними.Потоки могут использовать общую память для синхронизации самих себя - это называется синхронизированными объектами.Чтобы управлять потоками для системы потребителя / производителя, вы можете использовать очередь (структуру данных), а не систему сообщений.(см. пример здесь: C # производитель / потребитель ).

Другое возможное решение (которое я бы не рекомендовал): Вы можете использовать GetThreadId для возврата идентификатора данного собственного потока.Тогда все, что вам нужно найти, - это дескриптор потока и передать его этой функции.GetCurrentThreadId возвращает идентификатор текущего потока.Там вы можете получить доступ к его имени свойства.

1 голос
/ 05 февраля 2012

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

0 голосов
/ 05 февраля 2012

Сообщение - это просто вызов метода, и для вызова метода сначала необходим объект экземпляра, который предоставляет некоторые методы для вызова, поэтому отправка сообщения потоку означает поиск активного объекта, который находится в этом потоке, и вызов его конкретный метод.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...