9

5月 19

 

あるプログラムの変数を外部から操作したい場合の解決法

先日、上司が作ったpythonプログラムのグローバル変数を、外部からのプログラムによって書き換えたいという要求が起こった。

プログラム内でグローバル変数として確保されているメモリ領域を他のプログラムから直接書き換える、なんてことできるのだろうかと調べてみたら、プロセス間通信というのがそれらしいことがわかった。

しかしチラっと説明を見てみるとかなり面倒くさいことが発覚。
そりゃそうだ。ちょっと考えてみれば結構深いところを触らなければいけないことくらいはわかる。

そうして思いついたのは以下の2つ

  1. 環境変数を使ってプログラム間で変数の値を共有する
  2. 中継ファイルを一つ作る

1の方法では不可能だった。
Linux上のプログラムはOS全体の環境変数について読み込むことは出来ても書き換えることはできない。

プログラム上で書き込むことができるように見えても、それはそのプロセスにおいての環境変数が書き換わるだけで、他のプログラムから環境変数にアクセスすると、その値は書き換わってはいないのだった。

次に2の方法を試す。
これはまあ問題ないだろうと思いつつ実装してみると、やはり期待どおり動いた。

そこで友人のdyama氏(https://dyama.orgの運営者)からpipeを使ってはどうかというご提案をいただく。

pipeというのは文字通りfifoなpipeなわけだが、簡単に挙動を説明するとこんな感じ

#terminal A
$mkfifo pipe
$tail -f pipe

#terminal B
$echo "hoge" > pipe

とすると、ターミナルAの方でhogeという文字列が表示される

#terminal A
$tail -f pipe
hoge

この仕組を使って、2つのプログラム間での通信をさせて、外部プログラム(プログラムB)からコマンドを送り、それをpythonプログラム(プログラムA)で処理をするという形にした。

簡単な図にするとこう

スクリーンショット 2019 05 09 10 26 14

他プログラムから自プログラムの変数への介入をさせたいプログラムAは、もともとのメインループに加えてスレッドを実装し、一秒ごとにpipeファイルを読みにいく挙動を付け加えた。

さほどスピードが必要とされる処理ではなかったので一秒に一回で十分だった。

I/Oの時間すら惜しいスピードが求められる処理であれば、プロセス間通信を使う他ないのかなと思うが、ひとまずこれで十分に使えるものが出来たので満足です。




No comments yet, be the first.

コメントを残す