Как точно вызывать функцию каждые n миллисекунд в реальном времени? - PullRequest
0 голосов
/ 01 декабря 2018

Если я правильно понимаю, setInterval(() => console.log('hello world'), 1000) поместит функцию в некоторую очередь задач для запуска.Но если перед ним стоят другие задачи, он не будет работать точно с 1000 миллисекунд или каждый раз.

В одной сложной программе можно также выполнять вызовы некоторых функций каждую n миллисекундуточно в реальном времени с помощью node.js?

Ответы [ 4 ]

0 голосов
/ 01 декабря 2018

Если я правильно понимаю, setInterval (() => console.log ('hello world'), 1000) поместит функцию в некоторую очередь задач для запуска.Но если перед ним стоят другие задачи, он не будет работать точно с 1000 миллисекунд или каждый раз.

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

Водна сложная программа, возможно ли также совершать вызовы какой-либо функции каждую n миллисекунду точно в реальном времени с помощью node.js?

Нет, это невозможно сделать в node.js.node.js запускает ваш Javascript как однопоточный, он управляется событиями и не является приоритетным.Все это означает, что вы не можете полагаться на код, запущенный в точное реальное время.

Что происходит под покровом в файле node.js, так это то, что вы устанавливаете таймер на определенное время в будущем.Этот таймер регистрируется в цикле событий node.js, поэтому каждый раз, когда он проходит через цикл событий, он будет проверять наличие ожидающих таймеров.Но он проходит через цикл обработки событий только тогда, когда завершается работа другого кода, который работал до того, как таймер был готов к срабатыванию.Вот последовательность событий:

  • Выполнить некоторый код
  • Установить таймер на некоторое время в будущем (скажем, время X)
  • Выполнить еще какой-нибудь код
  • Некоторое время ничего не делать
  • Запустить еще немного кода (пока этот код выполняется, время X проходит - время для запуска вашего таймера)
  • Предыдущий блок кода завершает работу иЭлемент управления возвращается обратно в цикл событий node.js в момент времени X + n (через некоторое время после срабатывания таймера X).
  • Цикл событий проверяет наличие ожидающих таймеров.Он находит таймер и вызывает его обратный вызов в момент времени X + n.

Таким образом, единственный способ, которым ваш таймер вызывается примерно в момент времени X, это если node.js больше ничего не нужно делать в точное времяX. Если ваша программа когда-либо делает что-то еще, вы не можете гарантировать, что ваша программа будет свободна точно в то время, когда X будет запускать таймер именно тогда, когда вы хотите, чтобы он работал.node.js НЕ является системой реального времени.однопотоковый и не упреждающий означает, что таймеру, возможно, придется ждать, пока node.js завершит выполнение некоторых других задач, прежде чем он запустится, и, таким образом, нет никакой гарантии, что таймер будет работать точно в срок.Вместо этого он будет работать не так, как раньше X, когда в следующий раз интерпретатор сможет вернуться обратно в цикл обработки событий (выполнено то, что еще могло выполняться в это время).Это может быть близко ко времени X или это может быть значительное время после времени X.

Если вам действительно нужно что-то для точного запуска в определенное время, то вам, вероятно, нужна система с преимуществом (не узел).js) это намного больше в реальном времени, чем node.js.


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

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

0 голосов
/ 01 декабря 2018

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

Посмотрите пример в документации, если вы 'не знаком с модулем кластера: https://nodejs.org/docs/latest-v10.x/api/cluster.html

0 голосов
/ 01 декабря 2018

Но если перед ним стоят другие задачи, он не будет работать точно с 1000 миллисекунд или каждый раз.

Ваш вопрос на самом деле операционная система , при условии, что на компьютере установлена ​​какая-то (обычная) операционная система (например, Windows, Android, Linux, MacOSX и т. Д.).Я рекомендую прочитать Операционные системы: три простых компонента , чтобы узнать больше.

На практике на вашем компьютере есть множество других процессов , управляемых его операционной системой.система.Некоторые из них могут быть запущены.Ваш компьютер может быть в ситуации, когда он загружается достаточно другими процессами, так что он не может запускать ваши задачи или потоки точно каждую секунду.Читайте о thrashing .

Возможно, вы захотите использовать настоящую операционную систему реального времени .Но тогда, node.js, вероятно, не будет работать на нем.

Как вызывать функцию каждые n миллисекунд в реальном времени?

Вы не можете сделать это надежно. Поскольку ваш node.js процесс (на самом деле он однопоточный, на уровне системных потоков, см. pthreads (7) и ответ jfriend00 )может не получить достаточно ресурсов от вашей ОС (поэтому, если другие процессы загружают ваш компьютер слишком много, node.js будет голодать и не сможет развиваться так, как вы хотите; также помните о возможных инверсия приоритетов ).

В Linux см. Также shed (7) , chrt (1) , renice (1)

0 голосов
/ 01 декабря 2018

Я предлагаю сделать крон , который будет запускаться каждые n секунд.Если ваша программа сложна и может занять больше времени, тогда вы можете использовать async.

npm install cron

var CronJob = require('cron').CronJob;
new CronJob('* * * * * *', function() {
   console.log('You will see this message every second');

   callYourFunc();

}, null, true, 'America/Los_Angeles');

Подробнее читайте ссылка

...