Для подсказок посмотрите на имя имени класса, которое выдает ошибку и номер строки, например: Ошибка компиляции [ERROR] \ applications \ xxxxx.java: [44,30] ошибка: не удается найти символ
Еще одна причина - неподдерживаемый метод для java-версии: jdk7 vs 8. Проверьте свой% JAVA_HOME%
Действительно.
Для семейства функций, которые обрабатывают io_service
, run()
является единственным с ограничениями:
Функция
blockquote>run()
не должна вызываться из потока, который в настоящее время вызывает один изrun()
,run_one()
,poll()
илиpoll_one()
на том же объектеio_service
.Однако я склонен думать, что в документации также должно быть указано то же замечание для
run_one()
, поскольку вложенный вызов может привести к его блокировке неограниченно для любого из следующих случаев [1]:
- единственная работа в
io_service
- это выполняемый в настоящий момент обработчик- для реализаций портов завершения ввода-вывода, единственная работа была отправлена из текущего обработчика и
io_service
имеет подсказку о параллельности1
Для портов завершения ввода-вывода Windows демультиплексирование выполняется во всех потоках, обслуживающих
io_service
с помощьюGetQueuedCompletionStatus()
. На высоком уровне потоки, вызывающиеGetQueuedCompletionStatus()
, функционируют так, как если бы они были частью пула потоков, позволяя ОС отправлять работу в каждый поток. Поскольку ни один поток не отвечает за операции демультиплексирования с другими потоками, вложенные вызовыpoll()
илиpoll_one()
не влияют на диспетчеризацию операций для других потоков. В документации указано:Демультиплексирование с использованием портов завершения ввода-вывода выполняется в всех потоках, которые вызывают
blockquote>io_service::run()
,io_service::run_one()
,io_service::poll()
илиio_service::poll_one()
.
Для всех других систем механизмов демультиплексирования одноразовый сервис
io_service
используется для операций демультиплексирования операций ввода-вывода. Точный механизм демультиплексирования можно найти в Замечаниях по реализации платформы :Демультиплексирование с использованием [
blockquote>/dev/poll
,epoll
,kqueue
,select
] выполняется в одном потоков, который вызываетio_service::run()
,io_service::run_one()
,io_service::poll()
илиio_service::poll_one()
.Реализация механизма демультиплексирования немного отличается, но на высоком уровне:
- у
io_service
есть главная очередь, из которой потоки потребляют готовые к выполнению операции для выполнения- каждого вызова процесс
io_service
создает приватную очередь в стеке, которая используется для управления операциями в режиме блокировки- , в конечном итоге происходит синхронизация с основной очередью, где происходит блокировка и операции частной очереди
Когда
io_service
сконструирован , построенный , он может быть предоставлен в основной очереди, информируя другие потоки и позволяя им потреблять из основной очереди. подсказка параллелизма , предполагающая, сколько потоков реализовано ион должен позволять работать одновременно. Когда реализации портов завершения ввода-вывода снабжены подсказкой параллелизма1
, они оптимизированы для максимально возможного использования частной очереди и отсрочки синхронизации с основной очередью. Например, когда обработчик отправляется черезpost()
:
- , если он вызван извне обработчика, тогда
io_service
гарантирует безопасность потока, поэтому он блокирует основную очередь перед тем, как обходить обработчик.- , если он вызывается из обработчика, отправленный обработчик помещается в очередь в приватную очередь, откладывает отсрочку синхронизации с основной очередью до тех пор, пока не будет необходимо.
Когда вложенный
poll()
илиpoll_one()
, становится необходимым, чтобы частная очередь была скопирована в основную очередь, так как операции, которые будут выполняться, будут потребляться из основной очереди. Этот случай явно проверен в реализации :// We want to support nested calls to poll() and poll_one(), so any handlers // that are already on a thread-private queue need to be put on to the main // queue now. if (one_thread_) if (thread_info* outer_thread_info = ctx.next_by_key()) op_queue_.push(outer_thread_info->private_op_queue);
Если не указана никакая подсказка параллелизма или любое значение, отличное от
1
, то отправленные обработчики синхронизируются в основной очереди каждый раз. Поскольку частную очередь не нужно копировать, вложенные вызовыpoll()
иpoll_one()
будут работать как обычно.
1. В проекте networking-ts отмечается, что
run_one()
нельзя вызывать из потока, который в настоящее время вызываетrun()
.
Является ли вызов asio :: io_service :: poll () или poll_one () вложенным или рекурсивным способом (т. е. изнутри обработчика) действительным?
blockquote>Ситаксически, это действительно. Но, его не очень хорошая проблема в каждом обработчике, вы должны запустить poll (). Кроме того, ваша трассировка стека будет расти до очень больших размеров, и вы можете столкнуться с большими проблемами со стеком.