Help us understand the problem. What is going on with this article?

Command::spawnのデザイン(unix)

Command::spawnのデザイン(unix)

by kubo39
1 / 17

まえがき

  • std::processはポータブルな実装だがにここではunix着目する

プロセス起動

  • 新しいプロセスを立ち上げてプログラムを実行する
  • サブプロセスと言ったりもする

プロセス

  • プログラムを実行している主体
  • いろいろ状態をもってる
    • メモリ空間
    • ファイルディスクリプタ
    • 環境変数

prcess::Command

  • プロセス起動を行うためのAPI
    • 実装はポータブル(Posix/Windows)
    • UNIXでいうfork-execを行う
  • シェルを経由する専用APIは用意しない
    • newやargの引数に sh -c を渡せばできる

イメージ

  • 以下の例ではシェルを経由して実行
    • output で出力を受け取るまで暗黙にwait
let output = Command::new("sh")
                     .arg("-c")
                     .arg("echo hello")
                     .output()
                     .expect("failed to execute process");

デザイン

  • Command::new 時点ではプロセスを生成しない
    • spawn などを呼ぶまでの間にやりたいことを設定
      • 引数の追加(arg/args)
      • リダイレクト(stdin/stdout/stderr)
      • 環境変数の追加/クリア(env_clear)
      • カレントディレクトリ(current_dir)

デザイン

  • waitするかどうかはAPIによって変わる
    • spawnはwaitしないので親が明示的に行う
    • outputやstatusは当然行う

spawn

  • ジェネリックなプロセス起動API
  • std::process::Child を返す
    • 子プロセスのPIDをもつ
    • waitをメソッドにもつ

spawnの内部実装

  • 条件が合えば posix_spawn を使う
  • そうでない場合 forkexec を使う

posix_spawn

  • fork-execまで一気にやってくれるAPI
  • 現時点でいくつかのプラットフォームで使える
    • Linux/Glibc2.24+, MacOS, FreeBSD

posix_spawnを使う意図

  • メモリを複製しない実装が使われることが多い
  • fork-exec間に差し込めない処理もある
    • current_dir など使ったらforkを使う

before_exec

  • UNIXなシステムのみ存在
    • Windowsではそもそも不可能
  • fork-exec間で行いたい処理をフック可能
    • 他ではPythonの preexec_fn などがある
  • リダイレクトや環境変数以外にもやりたいことはある
    • リソース管理 (例: core dump)
    • fdのclose処理を書きたいかも

before_execは問題ないのか

  • 任意の処理が記述できてしまう
    • fork-exec間はasync-signal-safeな関数のみ使うべき
    • 危険性はドキュメントで注意喚起している
      • Pythonも同様

FDの挙動

  • 他の言語のように3番以降のFDをcloseするAPIを提供していない
    • Rustのstd自体はCLOEXEC前提
      • execのときにcloseするフラグ
    • Cのライブラリ関数は保証がない
      • リークしちゃうかも

過去の議論


spawnのまとめ

  • プロセス起動のプリミティブなAPI
  • fork+属性設定+exec
    • posix_spawnを使えるときは使う
  • before_exec で振る舞いを自由に記述できる
    • 注意は必要
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away