Потоки

В упрощенном виде программу можно представить как последовательность инструкций, которые разработчик сформировал для компьютера. Основным исполнителем инструкций в компьютере является центральный процессор. Современные компьютеры, как правило, оснащаются процессорами с несколькими ядрами, что равноценно тому, что в них несколько процессоров. Однако количество программ, которые пользователь может захотеть запустить параллельно, практически, не ограничено. Таким образом, число программ всегда во много раз больше доступных ядер/процессоров. В связи с этим каждое ядро на самом деле разделяет свое рабочее время между несколькими разными программами: выделит 1 миллисекунду на выполнение инструкций одной программы, потом 1 миллисекунду — для инструкций другой, потом — третей, и так далее, по кругу. Поскольку переключение происходит очень быстро, пользователь этого не замечает: для него все программы выполняются как бы параллельно и одновременно.

Для того чтобы процессор мог приостановить выполнение инструкций одной программы, а потом возобновить её работу с прежнего места (после того как он незаметно переключался на инструкции других "параллельных" программ), он должен уметь неким образом сохранять и восстанавливать промежуточное состояние каждой программы: текущую инструкцию, переменные, возможно, открытые файлы, сетевые подключения, и так далее. Вся эта совокупность ресурсов и данных, которые требуются программе для нормальной работы вместе с текущей позицией в последовательности инструкций, называется контекстом выполнения программы. Операционная система, по сути, предназначена для того, чтобы создавать такие контексты под каждую программу по требованию пользователя (или других программ). Каждый такой активный контекст и называется потоком. Многие программы запрашивают для себя много потоков, потому что их функционал подразумевает параллельное ведение нескольких активностей. И MetaTrader 5 — тоже в их числе. Загрузка котировок по множеству символов, построение графиков, реакция на действия пользователя — все это требует потоков. Но плюс ко всему отдельные потоки выделяются и MQL-программам.

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

Одно из важных свойств потока следует из его определения и назначения: он поддерживает лишь последовательное выполнение указанных инструкций одна за другой. В каждый момент времени в одном потоке исполняется только одна инструкция. Если в программе написан бесконечный цикл, поток "застрянет" на этой инструкции и никогда не доберется до инструкций ниже него. Долгие вычисления также могут создавать эффект бесконечного цикла: они загрузят процессор и не дадут выполниться другим действиям, результаты которых, возможно, ожидает пользователь. Именно поэтому эффективные расчеты в индикаторах важны для гладкой работы графического интерфейса.

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

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