Система
Модуль System предоставляет функции, которые взаимодействуют напрямую с виртуальной машиной (ВМ) или системой хоста.
Время
Модуль System также предоставляет функции работы со временем, возвращая различные временные значения, хранимые системой, с поддержкой разных единиц измерения времени.
Одна из сложностей, связанных с использованием системного времени, заключается в том, что оно может быть скорректировано. Например, при переходе на летнее/зимнее время системные часы будут скорректированы, часто добавляя или удаляя один час. Мы называем такие изменения «временными скачками» (time warps). Чтобы понять, как такие изменения могут быть вредны, рассмотрим следующий код:
## DO NOT DO THIS prev = System.os_time() # ... execute some code ... next = System.os_time() diff = next - prev
Если во время выполнения кода системные часы изменяются, может оказаться, что какой-то код, выполненный за 1 секунду, будет отражён как занявший более 1 часа! Для решения таких проблем ВМ предоставляет монотонное время через System.monotonic_time/0, которое никогда не уменьшается и не «прыгает»:
## DO THIS prev = System.monotonic_time() # ... execute some code ... next = System.monotonic_time() diff = next - prev
В целом, ВМ предоставляет три измерения времени:
-
os_time/0- время, возвращаемое ОС. Это время может быть скорректировано вперёд или назад без ограничений; -
system_time/0- представление ВМ оos_time/0. Системное время и время ОС могут не совпадать при временных скачках, хотя ВМ стремится их согласовать. Это время не является монотонным (то есть может уменьшаться), так как его поведение настраивается режимом временных скачков ВМ; -
monotonic_time/0- монотонно возрастающее время, предоставляемое виртуальной машиной Erlang.
Функции времени в этом модуле работают в :native единицах (если не указано иное), которые зависят от ОС. В большинстве случаев все вычисления производятся в :native единицах для избежания потери точности, и в конце вызывается convert_time_unit/3 для преобразования в определённую единицу времени, например, :millisecond или :microsecond. Для получения дополнительной информации см. тип time_unit/0.
Для более подробного ознакомления с поддержкой ВМ различных временных измерений см. главу о времени и его корректировке в документации Erlang.
Обзор
Типы
- time_unit()
Единица измерения времени, которая должна передаваться функциям, таким как
monotonic_time/1, и другим.
Функции
- argv()
Список аргументов командной строки.
- argv(args)
Изменяет аргументы командной строки.
- at_exit(fun)
Регистрирует обработчик завершения программы.
- build_info()
Информация о сборке Elixir.
- cmd(command, args, opts \\ [])
Выполняет заданную
commandсargs.- compiled_endianness()
Возвращает порядок байтов, с которым была скомпилирована система.
- convert_time_unit(time, from_unit, to_unit)
Преобразует
timeиз единицы времениfrom_unitв единицу времениto_unit.- cwd() устаревшая
Текущая рабочая директория.
- cwd!() устаревшая
Текущая рабочая директория, исключение при ошибке.
- delete_env(varname)
Удаляет переменную окружения.
- endianness()
Возвращает порядок байтов.
- find_executable(program)
Находит исполняемый файл в системе.
- get_env()
Возвращает все переменные окружения системы.
- get_env(varname)
Возвращает значение заданной переменной окружения.
- get_pid()
Идентификатор процесса виртуальной машины Erlang.
- halt(status \\ 0)
Немедленно останавливает систему выполнения Erlang.
- monotonic_time()
Возвращает текущее монотонное время в
:nativeединицах измерения.- monotonic_time(unit)
Возвращает текущее монотонное время в заданной единице измерения.
- os_time()
Возвращает текущее системное время.
- os_time(unit)
Возвращает текущее системное время в заданной единице
unit.- otp_release()
Возвращает номер версии Erlang/OTP.
- put_env(enum)
Устанавливает несколько переменных окружения.
- put_env(varname, value)
Устанавливает значение переменной окружения.
- schedulers()
Возвращает количество планировщиков в ВМ.
- schedulers_online()
Возвращает количество активных планировщиков в ВМ.
- stacktrace()
Устаревший механизм получения последнего стека исключений.
- stop(status \\ 0)
Безопасно останавливает систему выполнения Erlang.
- system_time()
Возвращает текущее системное время в
:nativeединицах измерения.- system_time(unit)
Возвращает текущее системное время в заданной единице измерения.
- time_offset()
Возвращает текущее смещение времени между монотонным временем Erlang ВМ и системным временем Erlang ВМ.
- time_offset(unit)
Возвращает текущее смещение времени между монотонным временем Erlang ВМ и системным временем Erlang ВМ.
- tmp_dir()
Директория для временных файлов.
- tmp_dir!()
Директория для временных файлов, исключение при ошибке.
- unique_integer(modifiers \\ [])
Генерирует и возвращает целое число, уникальное в текущей инстанции.
- user_home()
Директория пользователя.
- user_home!()
Директория пользователя, исключение при ошибке.
- version()
Информация о версии Elixir.
Типы
time_unit()
time_unit() :: :second | :millisecond | :microsecond | :nanosecond | pos_integer()
Единица измерения времени, которая должна передаваться функциям, таким как monotonic_time/1, и другим.
Единицы измерения :second, :millisecond, :microsecond и :nanosecond управляют значением, возвращаемым функциями, которые принимают единицу измерения времени.
Единицей измерения также может быть строго положительное целое число. В этом случае оно представляет «части на секунду»: время будет возвращено в 1 / parts_per_second секунды. Например, использование единицы измерения :millisecond эквивалентно использованию 1000 как единицы измерения (поскольку время будет возвращено в 1/1000 секунды — миллисекунды).
Функции
argv()
argv() :: [String.t()]
Список аргументов командной строки.
Возвращает список аргументов командной строки, переданных программе.
argv(args)
argv([String.t()]) :: :ok
Изменяет аргументы командной строки.
Изменяет список аргументов командной строки. Используйте с осторожностью, так как это уничтожает всю предыдущую информацию argv.
at_exit(fun)
at_exit((non_neg_integer() -> any())) :: :ok
Регистрирует обработчик завершения программы.
Регистрирует функцию, которая будет вызвана по завершении выполнения программы. Полезна для вызова обработчика в режиме «скрипта».
Обработчик всегда выполняется в другом процессе, нежели тот, в котором он был зарегистрирован. Вследствие этого, любые ресурсы, управляемые вызывающим процессом (таблицы ETS, открытые файлы и т. д.), не будут доступны к моменту вызова функции обработчика.
Функция должна принимать код состояния завершения в качестве аргумента.
build_info()
build_info() :: map()
Информация о сборке Elixir.
Возвращает список ключевых слов с версией Elixir, коротким хэшем Git-ревизии и датой компиляции.
cmd(command, args, opts \\ [])
cmd(binary(), [binary()], keyword()) ::
{Collectable.t(), exit_status :: non_neg_integer()} Выполняет заданную command с args.
command ожидается как исполняемый файл, доступный в переменной окружения PATH, если не указан абсолютный путь.
args должно быть списком бинарных файлов, которые исполняемый файл получит в качестве аргументов. Это означает, что:
- переменные окружения не будут интерполированы
- расширение шаблонов не произойдёт (если
Path.wildcard/2не используется явно) - аргументы не нужно экранировать или заключать в кавычки для безопасности оболочки
Эта функция возвращает кортеж, содержащий собранный результат и код завершения команды.
Внутренне, эта функция использует Port для взаимодействия с внешним миром. Однако, если вы планируете запускать долго выполняющуюся программу, порты гарантируют, что устройства stdin/stdout будут закрыты, но это не приводит к автоматическому завершению программы. Документация модуля Port описывает эту проблему и возможные решения в разделе "Процессы-зомби".
Примеры
iex> System.cmd("echo", ["hello"])
{"hello\n", 0}
iex> System.cmd("echo", ["hello"], env: [{"MIX_ENV", "test"}])
{"hello\n", 0}
iex> System.cmd("echo", ["hello"], into: IO.stream(:stdio, :line))
hello
{%IO.Stream{}, 0} Параметры
-
:into- вставляет результат в указанный коллектор, по умолчанию"" -
:cd- каталог для запуска команды -
:env- перечисляемый список кортежей, содержащих имена и значения переменных окружения в бинарном виде -
:arg0- задаёт arg0 команды -
:stderr_to_stdout- перенаправляет stderr в stdout, когдаtrue -
:parallelism- еслиtrue, VM будет планировать задачи порта для повышения параллельности в системе. Если установленоfalse, VM будет пытаться выполнять команды немедленно, улучшая задержки за счёт снижения параллельности. Значение по умолчанию можно задать при запуске системы, передав параметр "+spp" в--erl.
Причины ошибок
Если переданы некорректные аргументы, ArgumentError будет вызван System.cmd/3. System.cmd/3 также ожидает строго определённый набор параметров и будет генерировать исключение, если передан неизвестный или некорректный параметр.
Кроме того, System.cmd/3 может завершиться ошибкой по одной из POSIX причин, описанных ниже:
-
:system_limit- все доступные порты в эмуляторе Erlang заняты -
:enomem- не хватает памяти для создания порта -
:eagain- больше нет доступных процессов операционной системы -
:enametoolong- внешняя команда слишком длинная -
:emfile- больше нет доступных дескрипторов файлов (для процесса операционной системы, в котором работает эмулятор Erlang) -
:enfile- таблица файлов заполнена (для всей операционной системы) -
:eacces- команда не указывает на исполняемый файл -
:enoent- команда не указывает на существующий файл
Команды оболочки
Если вы хотите выполнить доверенную команду внутри оболочки с каналами, перенаправлением и т.д., пожалуйста, обратитесь к :os.cmd/1.
compiled_endianness()
compiled_endianness() :: :little | :big
Возвращает порядок байтов, с которым была скомпилирована система.
convert_time_unit(time, from_unit, to_unit)
convert_time_unit(integer(), time_unit() | :native, time_unit() | :native) :: integer()
Преобразует time из временной единицы from_unit во временную единицу to_unit.
Результат округляется с помощью функции floor.
convert_time_unit/3 принимает дополнительную временную единицу (отличную от тех, что в типе time_unit/0), называемую :native. :native — это временная единица, используемая системой выполнения Erlang. Она определяется при запуске системы выполнения и остаётся неизменной до её остановки. Чтобы определить, чему соответствует единица :native в системе, вы можете вызвать эту функцию, чтобы преобразовать 1 секунду во временную единицу :native (т.е., System.convert_time_unit(1, :second, :native)).
cwd()
cwd() :: String.t() | nilЭта функция устарела. Используйте File.cwd/0 вместо неё.
Текущий рабочий каталог.
Возвращает текущий рабочий каталог или nil если он недоступен.
cwd!()
cwd!() :: String.t()Эта функция устарела. Используйте File.cwd!/0 вместо неё.
Текущий рабочий каталог, исключение при ошибке.
Возвращает текущий рабочий каталог или вызывает RuntimeError.
delete_env(varname)
delete_env(String.t()) :: :ok
Удаляет переменную окружения.
Удаляет переменную varname из окружения.
endianness()
endianness() :: :little | :big
Возвращает порядок байтов.
find_executable(program)
find_executable(binary()) :: binary() | nil
Находит исполняемый файл в системе.
Эта функция ищет исполняемый файл, заданный его именем, используя переменную окружения PATH в Unix и Windows. Она также учитывает правильное расширение исполняемого файла для каждой ОС, поэтому для Windows она будет искать файлы с расширениями .com, .cmd или похожими.
get_env()
get_env() :: %{optional(String.t()) => String.t()} Возвращает все системные переменные окружения.
Возвращаемое значение — это карта, содержащая пары имя-значение. Имена переменных и их значения — это строки.
get_env(varname)
get_env(String.t()) :: String.t() | nil
Возвращает значение заданной переменной окружения.
Возвращаемое значение переменной окружения varname — это строка или nil если переменная окружения не определена.
get_pid()
get_pid() :: binary()
Идентификатор процесса VM Erlang.
Возвращает идентификатор процесса текущего эмулятора Erlang в формате, наиболее часто используемом средой операционной системы.
Для получения дополнительной информации см. :os.getpid/0.
halt(status \\ 0)
halt(non_neg_integer() | binary() | :abort) :: no_return()
Немедленно останавливает систему выполнения Erlang.
Завершает систему выполнения Erlang без надлежащего завершения приложений и портов. Обратитесь к stop/1 для аккуратного завершения системы.
status должно быть целым неотрицательным числом, атомом :abort или бинарным значением.
-
Если целое число, система выполнения завершается со значением целого числа, которое возвращается операционной системе.
-
Если
:abort, система выполнения прерывается, создавая дамп ядра, если это разрешено в операционной системе. -
Если строка, создаётся дамп сбоя Erlang со статусом в качестве слогана, а затем система выполнения завершается со статусом 1.
Обратите внимание, что во многих платформах операционная система поддерживает только коды состояния от 0 до 255.
Для получения дополнительной информации см. :erlang.halt/1.
Примеры
System.halt(0) System.halt(1) System.halt(:abort)
monotonic_time()
monotonic_time() :: integer()
Возвращает текущее монотонное время во временной единице :native.
Это время монотонно увеличивается и начинается в неопределённый момент времени.
Встроенный компилятором.
monotonic_time(unit)
monotonic_time(time_unit()) :: integer()
Возвращает текущее монотонное время в заданной временной единице.
Это время монотонно увеличивается и начинается в неопределённый момент времени.
os_time()
os_time() :: integer()
Возвращает текущее системное время.
Результат возвращается во временной единице :native.
Это время может быть скорректировано вперёд или назад без ограничений и не является монотонным.
Встроенный компилятором.
os_time(unit)
os_time(time_unit()) :: integer()
Возвращает текущее системное время в заданной временной unit.
Это время может быть скорректировано вперёд или назад без ограничений и не является монотонным.
otp_release()
otp_release() :: String.t()
Возвращает номер версии Erlang/OTP.
put_env(enum)
put_env(Enumerable.t()) :: :ok
Устанавливает несколько переменных окружения.
Устанавливает новое значение для каждой переменной окружения, соответствующей каждой паре {key, value} в enum.
put_env(varname, value)
put_env(binary(), binary()) :: :ok
Устанавливает значение переменной окружения.
Устанавливает новое value для переменной окружения varname.
schedulers()
schedulers() :: pos_integer()
Возвращает количество планировщиков в VM.
schedulers_online()
schedulers_online() :: pos_integer()
Возвращает количество активных планировщиков в VM.
stacktrace()
Устаревший механизм получения последнего стека исключений.
Доступ к стеку исключений за пределами rescue/catch устарел. Если вы хотите поддерживать только Elixir v1.7+, вы должны получить доступ к __STACKTRACE__/0 внутри rescue/catch. Если вы хотите поддерживать более ранние версии Elixir, поместите System.stacktrace/0 внутри rescue/catch.
Обратите внимание, что Erlang VM (и, следовательно, эта функция) не возвращает текущий стек вызовов, а стек вызовов последней исключительной ситуации. Чтобы получить стек вызовов текущего процесса, используйте Process.info(self(), :current_stacktrace).
stop(status \\ 0)
(с 1.5.0)stop(non_neg_integer() | binary()) :: no_return()
Аккуратно останавливает систему выполнения Erlang.
Все приложения завершаются плавно, весь код загружается, и все порты закрываются перед завершением системы с вызовом halt/1.
status должно быть неотрицательным целочисленным значением, возвращаемым системой выполнения операционной системе.
Обратите внимание, что во многих платформах операционная система поддерживает только коды статуса 0-255.
Для получения дополнительной информации см. :init.stop/1.
Примеры
System.stop(0) System.stop(1)
system_time()
system_time() :: integer()
Возвращает текущее системное время в :native единицах времени.
Это представление времени в VM, соответствующее os_time/0. Они могут не совпадать в случае временных искажений, хотя VM стремится к их выравниванию. Это время не монотонно.
Встраивается компилятором.
system_time(unit)
system_time(time_unit()) :: integer()
Возвращает текущее системное время в заданных единицах времени.
Это представление времени в VM, соответствующее os_time/0. Они могут не совпадать в случае временных искажений, хотя VM стремится к их выравниванию. Это время не монотонно.
time_offset()
time_offset() :: integer()
Возвращает текущий временной сдвиг между монотонным временем Erlang VM и системным временем Erlang VM.
Результат возвращается в :native единицах времени.
См. time_offset/1 для получения дополнительной информации.
Встраивается компилятором.
time_offset(unit)
time_offset(time_unit()) :: integer()
Возвращает текущий временной сдвиг между монотонным временем Erlang VM и системным временем Erlang VM.
Результат возвращается в заданных единицах времени unit. Полученный сдвиг, добавленный к монотонному времени Erlang (например, полученному с помощью monotonic_time/1), даёт системное время Erlang, соответствующее этому монотонному времени.
tmp_dir()
tmp_dir() :: String.t() | nil
Записываемый временный каталог.
Возвращает записываемый временный каталог. Поиск каталогов выполняется в следующем порядке:
- каталог, указанный в переменной окружения TMPDIR
- каталог, указанный в переменной окружения TEMP
- каталог, указанный в переменной окружения TMP
-
C:\TMPв Windows или/tmpв Unix - в качестве последнего средства, текущий рабочий каталог
Возвращает nil, если ни один из вышеперечисленных каталогов не является записываемым.
tmp_dir!()
tmp_dir!() :: String.t()
Записываемый временный каталог, исключение при ошибке.
То же, что и tmp_dir/0, но вместо возвращения nil, если каталог временных файлов не установлен, генерирует исключение RuntimeError.
unique_integer(modifiers \\ [])
unique_integer([:positive | :monotonic]) :: integer()
Генерирует и возвращает целое число, уникальное в текущем экземпляре выполнения.
"Уникальность" означает, что эта функция, вызываемая со списком modifiers, никогда не вернёт одно и то же целое число более чем один раз в текущем экземпляре выполнения.
Если modifiers имеет значение [], то возвращается уникальное целое число (может быть положительным или отрицательным). Другие модификаторы могут быть переданы для изменения свойств возвращаемого целого числа:
-
:positive- возвращаемое целое число гарантированно будет положительным. -
:monotonic- возвращаемое целое число монотонно возрастает. Это означает, что в одном и том же экземпляре выполнения (но даже в разных процессах), целые числа, возвращаемые с использованием модификатора:monotonic, всегда будут строго меньше целых чисел, возвращаемых последующими вызовами с модификатором:monotonic.
Все перечисленные выше модификаторы могут быть объединены; повторяющиеся модификаторы в modifiers будут проигнорированы.
Встраивается компилятором.
user_home()
user_home() :: String.t() | nil
Домашний каталог пользователя.
Возвращает домашний каталог пользователя (независимо от платформы).
user_home!()
user_home!() :: String.t()
Домашний каталог пользователя, исключение при ошибке.
То же, что и user_home/0, но вместо возвращения nil, если домашний каталог пользователя не установлен, генерирует исключение RuntimeError.
version()
version() :: String.t()
Информация о версии Elixir.
Возвращает версию Elixir как двоичное значение.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.8.2/System.html