С++ boost:: thread выполнить код в основном потоке?

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

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

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

Как и в ObjectiveC выполнитьSelectorOnMaintThread

Ответ 1

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

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

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

Общая информация: Boost Asio io_service.run() - пример сообщения-сообщения

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

Ответ 2

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

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

    func_ptr function;
    bool finished;

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

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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