2

Даже после чтения http://krondo.com/?p=1209 или Does an asynchronous call always create/call a new thread? Я все еще смущен тем, как обеспечить асинхронные вызовы по однопоточной системе. Я объясню свое понимание и покажу свои сомнения.Асинхронная обработка с одной нитью

Один из примеров, которые я читал, описывал TCP-сервер, обеспечивающий асинхронную обработку запросов - пользователь вызывал бы метод, например. get(Callback c), и обратный вызов будет вызван через некоторое время. Теперь, моя первая проблема здесь - у нас уже есть две системы, один сервер и один клиент. Это не то, что я имею в виду, потому что на самом деле у нас есть по крайней мере два потока - один на сервере и один на стороне клиента.

Другим примером, который я прочитал, был JavaScript, так как это самый яркий пример однопоточной асинхронной системы с Node.js. То, что я не могу получить мой голова, может быть, мышления в Java терминах, заключается в следующем: если я выполнить код ниже (извинения за некорректный, вероятно, зверской синтаксис):

function foo(){ 
    read_file(FIle location, Callback c) //asynchronous call, does not block 
    //do many things more here, potentially for hours 
} 

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

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

Заранее благодарим всех за комментарии и указываем на мои ошибки по дороге.

Обновление: Благодарим за сообщение. Другие хорошие источники, которые помогли мне с этим здесь:

  1. http://www.html5rocks.com/en/tutorials/async/deferred/
  2. http://lostechies.com/johnteague/2012/11/30/node-js-must-know-concepts-asynchrounous/
  3. http://www.interact-sw.co.uk/iangblog/2004/09/23/threadless (.NET)
  4. http://ejohn.org/blog/how-javascript-timers-work/ (встроенные функции таймеров)
  5. http://www.mobl-lang.org/283/reducing-the-pain-synchronous-asynchronous-programming/
+0

Там может быть или не может быть фоновый поток неявно запускается в ожидании операции, но это совершенно непрозрачны и не имеет отношения к вашему коду JavaScript, который начал сам операцию. Основной цикл цикла потока JavaScript в веб-браузере (или NodeJS, FTM) является однопоточным. – Noseratio

ответ

2

Реальный ответ заключается в том, что это зависит от того, что вы подразумеваете под «одной нитью» ».

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

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

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

+0

SO, в скрипте Java мой вызов для загрузки файла с диска будет событием или серией событий, помещенных в очередь для обработки? Но так как это так, мой код на самом деле не является исполняемым потоком, так как может существовать только один поток, который, по сути, является основным потоком потока потоков в цепочке только очереди ... Итак, если основной поток при выполнении вытягивания событий должен быть явно другой поток, который планирует эти события iu.e. помещая их в эту очередь, не так ли? – Bober02

+0

Я не являюсь пользователем Javascript, поэтому я не могу ответить на это конкретно. Но помните, что у вас есть целая операционная система, плюс браузер или другая среда выполнения, в которой работает Javascript. У них есть собственные потоки/процессы с временными интервалами с вашим Javascript, а асинхронные операции в вашем Javascript могут быть переданы им. – keshlam

0

То, как я думаю об этом в JavaScript, является то, что есть очередь, которая содержит события. В старой версии Java-производителя/потребителя есть один потребительский поток, вытягивающий материал из этой очереди и выполняющий каждую функцию, зарегистрированную для получения текущего события. События, такие как асинхронные вызовы (завершение запросов AJAX), тайм-ауты или события мыши, попадают в очередь, как только они происходят. Один «потребительский» поток выталкивает их из очереди и находит любые заинтересованные функции, а затем выполняет их, он не может перейти к следующему событию, пока не завершит вызов всех функций, зарегистрированных на текущем. Таким образом, если у вас есть обработчик, который никогда не завершается, очередь просто заполняется - она ​​называется «заблокирована».

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

Таким образом, в вашем примере:

function foo(){ 
    read_file(location, function(fileContents) { 
     // called with the fileContents when file is read 
    }  
    //do many things more here, potentially for hours 
} 

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

НТН

Смежные вопросы