10.01.2014, 17:49
|
Профессор
|
|
Регистрация: 24.03.2011
Сообщений: 217
|
|
Потоки данных и параллельное выполнение функций
Всем привет!
Разбираюсь с логикой выполнения функций в nodejs.
Дело в том, что у меня есть цикл, который обрабатывает много данных и проводит сложные вычисления.
Я так понимаю, что добиться параллельного выполнения функций в одном потоке нельзя. Даже если вызвался callback - он не выполнится, пока в потоке на данный момент происходят вычисления и пока очередь не дойдет до него.
Я правильно понимаю?)
|
|
10.01.2014, 18:02
|
|
I am Student
|
|
Регистрация: 17.12.2011
Сообщений: 4,415
|
|
Сообщение от Dorian_bs
|
Даже если вызвался callback - он не выполнится, пока в потоке на данный момент происходят вычисления и пока очередь не дойдет до него.
|
Если к примеру запрос к базе данных идет, то запрос будет асинхроным и callback выполниться когда прийдет ответ из базы, а если к примеру использовать callback в forEach то эта операция будет синхронной.
Сообщение от Dorian_bs
|
Дело в том, что у меня есть цикл, который обрабатывает много данных и проводит сложные вычисления.
|
Просто пример как это можно сделать, сервер А принял запрос на длителььную задачу что бы не блокировать обработку запросов выполнения сложного вычесления передано серверу Б, после выполнения сервере Б, вызывается callback на сервере А и пользователю возврщается результат .
__________________
Цитата:
|
Если ограничения и условия описываются как "коробка", то хитрость в том что бы найти именно коробку... Не думайте о чем то глобальном - найдите коробку.
|
|
|
10.01.2014, 18:03
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Я уже писал тебе про это. В рамках потока всё выполняется последовательно, но ты можешь разбить свой цикл на множество подциклов и выполнять его поэтапно, т.е. прошёл n итераций, прервался, ждёшь пока выполнятся другие задания, потом опять начал и т.д.
Нужные функции в node для этого - это setImmediate и nextTick, НО если у тебя задача требует поддержки потоков в языке, то крайне глупо использовать для этого JS, возьми например Java.
|
|
10.01.2014, 18:07
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Сообщение от cyber
|
Если к примеру запрос к базе данных идет, то запрос будет асинхроным и callback выполниться когда прийдет ответ из базы, а если к примеру использовать callback в forEach то эта операция будет синхронной.
|
Ты написал глупости Всё зависит от интерфейса АПИ, тот же пресловутый forEach легко делается асинхронным с помощью дробления через setImmediate или nextTick (смотри либу async).
В случае асинхронного callback он выполнится не сразу как придёт, а сразу как до него дойдёт очередь после того, как он пришёл, т.е. если залочить поток бесконечным циклом, то callback никогда не всплывёт.
В общем нужно помнить, что пока JS что-то делает (бегает по циклам, складывает числа), то все уже пришедшие callback-и будут томится в темнице стека-событий ожидая освобождения потока.
Последний раз редактировалось kobezzza, 10.01.2014 в 18:12.
|
|
10.01.2014, 18:13
|
Профессор
|
|
Регистрация: 24.03.2011
Сообщений: 217
|
|
cyber, спасибо за ответ!
kobezzza, Вот нарисовал, как я представляю логику) Вернее как я начал представлять ее))
Получается благодаря nextTick мы прерываем выполнение функции до следующей итерации event-loop?
То есть даем возможность дальше выполниться всем остальным функциям?
А с новой итерацией уже выполняем то, что задано в nextTick.
Все верно?
|
|
10.01.2014, 18:14
|
|
I am Student
|
|
Регистрация: 17.12.2011
Сообщений: 4,415
|
|
Сообщение от kobezzza
|
Всё зависит от интерфейса АПИ, тот же пресловутый forEach легко делается асинхронным с помощью дробления
|
Я как пример говорю, про forEach в том виде в котором он есть.
Сообщение от kobezzza
|
В случае асинхронного callback он выполнится не сразу как придёт, а сразу как до него дойдёт очередь после того, как он пришёл, т.е. если залочить поток бесконечным циклом, то callback никогда не всплывёт.
|
Да, согласен тут я не уточнил что он становиться в очередь, и пока до него не дойдет очередь он не будет вызван.
Сообщение от kobezzza
|
(смотри либу async).
|
Хорошая либа
__________________
Цитата:
|
Если ограничения и условия описываются как "коробка", то хитрость в том что бы найти именно коробку... Не думайте о чем то глобальном - найдите коробку.
|
|
|
10.01.2014, 18:20
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Сообщение от Dorian_bs
|
kobezzza, Получается благодаря nextTick мы прерываем выполнение функции до следующей итерации event-loop?
То есть даем возможность дальше выполниться всем остальным функциям?
А с новой итерацией уже выполняем то, что задано в nextTick.
Все верно?
|
Не, никаких прерываний. Ты просто передаёшь в setImmediate функцию, и она выполнится на следующей итерации событийного цикла, т.е. искуственно разбиваешь свою функцию на множество подфункций. Но в остальном ход мыслей в нужном направлении движется.
Разница между nextTick и setImmediate в том, что одни функции выполняются до I/O,а другие после.
Тут следует сказать, что выполнение setTimeout и setInterval могут быть как до I/O так и после, т.е. их для этих целей лучше не юзать.
***
Прерывания кстати тоже возможны, с помощью генераторов (см. оператор yield, в node они уже поддеживаются).
Последний раз редактировалось kobezzza, 10.01.2014 в 18:38.
|
|
10.01.2014, 18:28
|
Профессор
|
|
Регистрация: 24.03.2011
Сообщений: 217
|
|
Сообщение от kobezzza
|
Разница между nextTick и setImmediate в том, что одни функции выполняются до I/O,а другие после.
|
kobezzza, То есть функции обернутые в setImmediate будут выполняться в конце следующей итерации?)
|
|
10.01.2014, 18:33
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Сообщение от Dorian_bs
|
kobezzza, То есть функции обернутые в setImmediate будут выполняться в конце следующей итерации?)
|
Ну грубо говоря да. А nextTick в конце текущей, поэтому setImmediate обычно юзают для "разгрузки" больших операций.
process.nextTick(function () {
console.log(1);
process.nextTick(function () {
console.log(2);
});
});
setImmediate(function () {
console.log(3);
process.nextTick(function () {
console.log(1);
process.nextTick(function () {
console.log(2);
});
});
});
console.log(4);
// 4 1 2 3 1 2
Последний раз редактировалось kobezzza, 10.01.2014 в 18:50.
|
|
10.01.2014, 18:51
|
Профессор
|
|
Регистрация: 24.03.2011
Сообщений: 217
|
|
kobezzza, большое спасибо! Теперь все куда более понятно!)
Сообщение от cyber
|
Просто пример как это можно сделать, сервер А принял запрос на длителььную задачу что бы не блокировать обработку запросов выполнения сложного вычесления передано серверу Б, после выполнения сервере Б, вызывается callback на сервере А и пользователю возврщается результат .
|
А вы не можете подсказать, существуют ли какие либо модули для обмена данными между работающими серверами?
|
|
|
|