c ++ boost :: thread выполнить код в основном потоке? - PullRequest
10 голосов
/ 20 мая 2011

Возможно ли после вызова boost :: thread, выполняющего некоторые инструкции, вернуться в основной поток?

Мой код основан на паттерне proactor, однако определенная функция может занять некоторое время, поэтому вЧтобы не блокировать всю программу, я создаю поток, выполняющий эту функцию.Когда эта функция заканчивается, мне нужно вызвать другую функцию, но она должна быть запущена в главном потоке.У меня есть пул соединений, который не является потокобезопасным, и я действительно хотел бы избежать мьютекса.

Есть ли стабильный способ запуска функции в главном потоке (вызов в другом потоке)?

Так же, как в ObjectiveC executeSelectorOnMaintThread

Ответы [ 5 ]

5 голосов
/ 20 мая 2011

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

struct message
{
    typedef void (*func_ptr)(void); //or whatever your function signature would be

    func_ptr function;
    bool finished;

    message(): function(NULL), finished(false) {}
};

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

Кстати, и эффективный способ заставить главный поток "ждать", не поддерживая его в цикле и не задействуя циклы ЦП, будетиспользовать семафор или переменную условия (например, boost::condition) между основным потоком и рабочим.

И еще одно замечание ... «очередь сообщений» - это просто std::queue<message> с соответствующим доступом к блокировке, который читает основной поток, а рабочий поток пишет.Также может быть другая очередь сообщений для рабочего потока, в которую записывает основной поток, и рабочий поток читает, если вам нужна двусторонняя связь между потоками.

2 голосов
/ 20 мая 2011

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

Обратите внимание, что на самом деле нить больше похожа на волокно (имеется в виду: если есть больше прядей)чем фактические потоки, нити будут мультиплексированы на доступные потоки).

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

Общая информация : Boost Asio io_service.run () является примером прокачки сообщений

Вотстраница образцов для Boost Asio: http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/examples.html

0 голосов
/ 05 апреля 2014

У меня была похожая ситуация.MFC диалог с бустом потоков.Чтобы решить эту проблему, я добавил сигналы 2 в поток поддержки и связал их с функциями-членами в диалоговом окне.когда сигналы поступили в функции-члены диалога, я проверил идентификатор потока.если идентификатор потока не совпадает с идентификатором потока диалога, я помещаю функцию повышения в очередь функций std :: queue (та же сигнатура).onidle, kickidle Я проверяю очередь и выполняю функции.

0 голосов
/ 21 января 2013

Если вы работаете в Visual Studio 2010, он всегда должен работать в режиме отладки. Однако из-за ошибки вам может потребоваться отключить, а затем снова включить «оптимизацию», чтобы заставить релиз работать.

0 голосов
/ 20 мая 2011

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

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

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