Коммуникация межпотока. Как отправить сигнал в другой поток

В моем приложении у меня есть два потока

  1. "основной поток", который занят большую часть времени
  2. "дополнительный поток", который отсылает некоторый Запрос HTTP и какие блоки, пока это не получает ответ.

Однако ответ HTTP может только быть обработан основным потоком, так как он полагается, это - локальная память потока и на неориентированных на многопотоковое исполнение функциях.

Я ищу способ сказать основной поток, когда ответ HTTP был получен и соответствующие данные. Основной поток должен быть прерван дополнительным потоком и обработать ответ HTTP как можно скорее, и впоследствии продолжать работать от точки, где это было прервано прежде.

  • Одним путем я могу думать о, то, что дополнительный поток приостанавливает основное использование потока SuspendThread, копирует TLS с основного потока с помощью некоторого встроенного ассемблера, выполняет саму обрабатывающую ответ функцию и возобновляет основной поток впоследствии.

  • Иначе в моих мыслях, устанавливая точку останова на некоторый определенный адрес во второй стандартной программе обратного вызова потоков, так, чтобы основной поток был уведомлен, когда вторые шаги указателя команд потоков на той точке останова - и поэтому - получили ответ HTTP.

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

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

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

6
задан Community 23 May 2017 в 11:51
поделиться

7 ответов

Это может быть один из тех случаев, когда человек работает над очень конкретной идеей, не переосмысливая общую картину. Не существует единого механизма, с помощью которого один поток может остановить выполнение в своем текущем контексте, пойти делать что-то другое и возобновить выполнение на той самой строке, с которой он откололся. Если бы это было возможно, то это в первую очередь опровергло бы цель существования потоков. Как вы уже упоминали, не отступая и пересматривая общую архитектуру, самый элегантный из ваших вариантов, кажется, использовать другой поток, чтобы ждать ответа HTTP, пусть он приостановить основной поток в безопасном месте, обрабатывать ответ по своему усмотрению, а затем возобновить основной поток. В этом сценарии вы можете переосмыслить, имеет ли потоколокальное хранение все еще смысл, или если что-то немного больше по объему будет более подходящим, так как вы можете потенциально тратить много циклов, копируя его каждый раз, когда вы прерываете основной поток.

.
4
ответ дан 17 December 2019 в 00:10
поделиться

Если ваш основной поток - это поток GUI, почему бы не послать ему сообщение Windows? Что мы все делаем, чтобы взаимодействовать с win32 GUI из рабочих потоков.

.
0
ответ дан 17 December 2019 в 00:10
поделиться

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

Лучше сказать, что вы пытаетесь сделать.

.
0
ответ дан 17 December 2019 в 00:10
поделиться

То, что вы описываете, это то, что делает QueueUserAPC. Но идея использования его для такого рода синхронизации меня немного смущает. Если Вы не знаете, что основной поток находится в безопасном месте для прерывания, то, вероятно, Вам не следует прерывать его.

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

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

.
2
ответ дан 17 December 2019 в 00:10
поделиться

Я, возможно, не понимаю вопроса, но СоздатьSemaphore и WaitForSingleObject должно сработать. Если один поток ждет семафор, то он возобновится, когда другой поток подаст на него сигнал.

Обновление на основе комментария: Основной поток может вызвать WaitForSingleObject с временем ожидания нулевым. В этой ситуации он немедленно возобновится, если семафор не будет сигнализировать. Затем основной поток мог проверять его на периодической основе

.
1
ответ дан 17 December 2019 в 00:10
поделиться

Похоже, что ответ должен быть найден из Microsoft's MSDN. Особенно из этого раздела о 'Synchronizing Execution of Multiple Threads'

.
0
ответ дан 17 December 2019 в 00:10
поделиться
[

] В этой ситуации я бы сделал пару вещей. В первую очередь, я бы перестроил работу, которую делает основной поток, чтобы разбить ее на как можно меньшие части. Это даст вам ряд безопасных мест, где можно прервать выполнение. Тогда вы хотите создать очередь работ, вероятно, с помощью слайда Microsoft. Слист даст вам возможность добавлять один поток, в то время как другой будет читать без необходимости блокировки.[

] [

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

].
0
ответ дан 17 December 2019 в 00:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: