SSブログ

バックグラウンドのアプリを軽くする [プログラミング]

「Macの手書き説明書」さんの「バックグラウンドで開いているアプリを劇的に軽くするPythonスクリプト」というエントリで知った。元ネタは「日曜研究室」さんのこの記事

同じ動作をする専用の簡単なアプリDesquanderを書いたので、それを紹介する。

元ネタの記事を見せてもらうと
1 killall -SIGSTOP firefox-bin
2 killall -SIGCONT firefox-bin
でアプリケーション(ここではFireFox)の動作を一時停止したり、継続したりできるらしい。

なに、それ?SIGTRAPとかSIGALRMじゃなくてSIGSTOPなの?

ちょこちょこ調べてみるとどうやらそういうシグナル(signal)があるらしい。全然知らなかった。すくなくとも昔のSytemVにはなかった。なぜそれが断言できるか、というとずっと昔、HP-UX(HP社のunix)でsignalを使ったプログラミングをする必要が出て、当時HP-UXはSystemVベースでsignalは19個しか定義されていなかったのをよく覚えている。僕のunixのシステムコールに関する知識はSystemV、4.2BSD時代から全然増えてない。

2.1  シグナルの由来

シグナル(signal)とはunixでOSの機能として実装されたプロセス間通信のメカニズムである。「ソフトウェア割り込み」であると説明されることが多い。プロセス間通信なので当然非同期的で、その意味で「割り込み」というのは正しい。また「ハードウェア割り込み」と同じメカニズムを使って実装されることも多かった。

unixでシグナルと言えば、暴走したプロセスを端末から殺すためにCtrl-C(コントロールキーと"C"を同時に押す)を入力するという作業で頻繁に使っている。これは端末からプロセスにSIGINTシグナルを送っていることになる。

シグナルが定義されたsignal.hを最初のほうから見てみるとわかるけど、もともとはOSにとって面倒なことが起きたときに、あるプログラムを稼働中のプロセスに対してそのことを知らせるためのものである。

例えば1番のSIGHUPは端末の回線が切れたときに知らせるためのものである。昔は音響カプラといったアナログの電話線経由で端末を繋いでunixを使うこともあって、不安定な回線だと使っている途中で切れた。この場合プログラム側から何かを出力しても誰も見ることはできないので、それをOSがプロセスに教えてやるのがこのSIGHUPである。

また、4番のSIGILLや10番のSIGBUSのようにあきらかにプログラムが暴走しているのがわかったときにもOSから送られる。SIGILLはプログラムを実行中のプロセスがCPUに存在しない命令を実行しようとしたとき、SIGBUSはバスエラーが発生したときに送られる。SIGIOT、SIGEMT、SIGFPE、SIGSEGVなど、これに似たシグナルがいくつか定義されているが、今では意味のないものも多い。これらのシグナルを受けたプロセス側はデフォルトの動作ではそこで終了する。

このようにシグナルはもともと、例外的な事態発生を知らせるためのものなので、便利なメカニズムというようなものではなくOSが自分の都合で送ってくるのが普通である。従ってシグナルの種類(シグナル番号)以外の付加的な情報は何もない。

2.2  シグナルによるプロセスの停止と継続

昔の僕の知ってるシグナルでは、プロセスを終了させたくなければ捕捉するか無視するかしかなかった。今回改めて見てみるとMacOS Xではシグナルが31個にも増えている(ターミナルからman signalで詳細が読める)。しかもDefault Action(デフォルト動作)に「stop process」なんていうのがあるのがわかる。SIGSTOP(シグナル番号17番)で停止してSIGCONT(シグナル番号19番)で再開するとなっている。

これはプロセスの状態に停止状態(psコマンドでstateに"T"と表示される)というのがあってそこへ遷移させるものらしい。この状態はおそらく、プロセススロットは保持されているけどスケジュールされない、と言う状態なんだろう。昔こんなのあったかなあ。そこまで覚えていないけど、readシステムコールなんかで入力待ちの状態に似ているので、昔にはなかったとしても拡張はそれほど問題ないだろう。

でもそれを使うことでプロセスを止めたり再開したりできる。最近の人には当たり前のことかもしれないけど、これを知らなかった僕にはすごく面白い。

2.3  Desquanderアプリ

ということで、SIGSTOP/SIGCONTという新しいおもちゃを貰って、ネタ元と同じようなことをするアプリを書いた。Desquanderという名前にした。「浪費をやめさせる(squanderしない)」というつもりのいいかげんな造語。アイコンもめちゃ適当。これを立ち上げると、そのとき実行しているアプリがリスト表示される。こんなふうに。

0223desquander0.png


リストには全部のアプリ(プロセス)ではなくドックに登録されるごく普通のアプリだけが表示されるようになっている。

右端のカラムのチェックボックスにチェックを入れたアプリは、バックグラウンドにまわるときにSIGSTOPシグナルが送られて、最前面(フォアグランド)に来たらSIGCONTシグナルが送られるようになっている。つまり最前面アプリでない限りCPUを消費しなくなる。逆に止まっているアプリも最前面に持ってくれば動き出すようになっている。

バックグラウンド専用アプリや、ことえりなんかの特殊なアプリはリストには上がらないので必要な動作を止める心配はない。またリストに自分自身(Descquander)も表示されるけど、これだけはチェックできないようにしてある。これを止めてしまうとチェックを入れたアプリともども2度と継続ができなくなってしまうのでこれは当然の措置。

これはDesquanderが起動しているあいだじゅうこの動作は続く。Desquanderを終了するとチェックを入れていたアプリも、そうでないアプリも通常動作に戻る。

一番下の「バックグラウンドではこのウィンドウを表示しない」のチェックボックスにチェックを入れると、Desquanderそのもののウィンドウはバックグラウンドでは表示されなくなる。ドックから呼んで(あるいはCmd-Tabで切り替えるなどして)最前面に持ってこない限り気にする必要はなくなる。実メモリも10MB程度しか保持しないし、CPU時間はアプリが切り替わるときにしか消費しないので実害は少ないと考えられる。

ひとつ問題がある。アプリにチェックを入れた状態でDesquanderを強制終了したら、チェックの入ったアプリはSIGCONTシグナルの送り元がなくなってしまうのでいつまでたっても停止したままになる。これはしょうがない。自力でターミナルからkillallコマンドでも入れてもらうか、止まっているアプリを強制終了してもらうしかない。

同様にDesquanderを経由せずに直接SGISTOPを受け取って止まっているアプリはDesquanderではわからない。一旦Desquanderでそのアプリに一度チェックを入れて外してから、もう一度入れ直せば整合性はとれることになる。

それと残念なことに、NSWorkSpaceの新しい機能を使っているのでDesquanderはMacOS X10.6以降でしか動作しない。僕が書くアプリは必ず、少なくともひとつ前のバージョンもサポートするという方針でいたんだけど、10.5ではすでに全然違う書き方をしないといけない。これはつらい。

アプリのダウンロードはここから

また、ソースファイルを含んだXCodeプロジェクトのダウンロードはここから

バグレポートもぜひ、よろしく。デバグも含めて3時間ほどで書いたのでおもしろい変なバグがあるかも。
nice!(0)  コメント(18)  トラックバック(0) 

nice! 0

コメント 18

Mint

ソフト開発お疲れ様です。
Pythonスクリプトに興味があり、さっそく使わせて頂きました。
現在のところ快適に動作しておりますが、一つ気になるバグ(?)がありました。
チェックを入れたアプリのウィンドウをDockにしまうとチェックを外さない限りDockから復帰が出来なくなるようです。
既知の問題かもしれませんが、少し気になったのでご報告させて頂きました。
by Mint (2011-02-24 10:04) 

decafish

コメント、バグ報告ありがとうございます。
確かにその通りです。この原因はわかりましたが、解決は難しそうです。
次の記事に書きますのでご覧下さい。
by decafish (2011-02-24 21:16) 

ゲスト

お疲れ様です。
大変使いやすく重宝しております。
一点気になった点をご報告します。自分はcmd+TABでアプリを切り替える機能を頻繁に使うのですが、これが一回で切り替わらないですね。連続で二回やらないと切り替わってくれません。
対応できるものでしたら、対応していただけると大変うれしく思います。
by ゲスト (2011-02-25 09:57) 

decafish

コメントありがとうございます。
僕もCmd+Tabで切り替えるのを頻繁に使っているのですが、僕の環境では変わりありません。なんだかバグを直したくないやつの言い訳みたいですがそうではないです。
もう少し詳しく状況を教えてもらえませんでしょうか。
よろしくお願いします。
by decafish (2011-02-25 21:26) 

ゲスト

お返事ありがとうございます。
アクティビティモニタで(応答なし)になったのを確認してから切り替えてみました。
OSX10.6.6で、Firefox3.6.13/Safari5.0.3は、連続クリックしないとウィンドウが前面に来ないです。
ただiTunes9.1.1は一回で前面にきます。spacesを使っているからでしょうか。
あと何を試せばいいでしょうか。
by ゲスト (2011-02-26 00:59) 

decafish

僕もまったく同じバージョンの環境ですが、Spacesを使っていないのでONにしてみました。しかし僕のiMac(mid2007/20")では再現しません(動作はDesquanderが動いてないときと変わりません)。
Cmd+Tabはドックが受け取って最前面のアプリを切り替えているようなのですが、詳細はよくわかりません。
僕も確認中ですが、ドックの設定などを変えてみて動作が変化しないか試してみてもらえないでしょうか。
また、FireFox、Safariで同じことが起こるアプリはないでしょうか。
by decafish (2011-02-26 09:02) 

nigorock

同じような状況になりましたのでご報告です。
Chrome9.0.597.102とThunderbird3.1.7で同じように連続クリックしないとウインドウが前面に来ない現象になりました。OSX10.6.6.です。同時に起動しているIllustratorは大丈夫でした。ただ、一度マウスでクリックしてCmd+Tabでやると1回はOKなのですが、次がダメという動きになりました。
1)Chromeをアクティブ、Thunderbirdをバックグラウンドに。
2)Thunderbirdをマウスでクリックしてアクティブに。
3)Cmd+TabでChromeを選ぶ。
4)問題なくアクティブに。
5)再度Cmd+TabでThunderbirdを選ぶ。
6)アクティブにならずもう一度選ぶとアクティブになる。
という感じです。
ちなみにSafari5.0.3はゲストさんと同様にアクティブになりませんでしたが、iTunes10.1.2は問題なかったです。
by nigorock (2011-02-26 12:31) 

decafish

詳細なレポート大変ありがとうございます。
ChromeとThunderbirdでやってみましたが、僕の環境ではやはり再現しませんでした(Thunderbirdは使ってないのでからっぽでしたが)。
ドックの動作の問題だろうと思っていたのですが、ひょっとするとタイミングの微妙な問題かも知れません。kernelにとってはプロセスの状態遷移を引き起こすシステムコールはリエントラントではありませんが、プロセスの状態遷移はそれなりの時間がかかります。この部分はDarwinとして公開されているので確認可能です(大変ですけど)。
そのへんの問題かも知れません。もう少し検討の時間を下さい。
もしそうだとすると、案外面白いかも。
by decafish (2011-02-26 19:34) 

ゲスト

ご無沙汰してすいません。お疲れ様です。
他の方でも再現したんですね。自分だけかと思っていたので、よかった(?)です。
あれからいろいろやってみたんですが、nigorockさんと同じくイラストレーターは大丈夫でした。同様にフォトショップ、Dw CS5も大丈夫です。
Mailはなったりならなかったりです。まあMailを殺しておくのは非現実的なので、あまり参考にならないですかね。
あと小出しですいませんが、うちはiMacMB325でマルチ画面にしています。
by ゲスト (2011-03-01 17:39) 

ゲスト

連投すいません。書き忘れました。
Mail文中などのURLクリックでFirefoxにURLを送るとFirefoxは動く(表示する)んですけど、ウィンドウは前面に来ないという現象もあります。
by ゲスト (2011-03-01 18:14) 

decafish

情報ありがとうございます。
僕のところではいろいろやってみましたが、なかなか再現しません。アプリによる、というのも不思議です。
まもなく1.1をリリースするつもりですので、申し訳ありませんがそちらの方の確認もよろしくお願いします。

by decafish (2011-03-01 23:30) 

ゲスト

お、新バージョン来るんですね。楽しみにしてまーす。
by ゲスト (2011-03-03 11:37) 

decafish

ありがとうございます。
ご指摘のCmd-Tab問題はなかなか解決できなさそうで、それ以外の整備をしたものになります。何かヒントになる動作をする別のアプリができないか考えていますが、なかなか難しいです。
1.1でまた動作確認をしていただけるとありがたいです。
よろしくお願いします。
by decafish (2011-03-03 21:44) 

mimiko

ダウンロードできませんo(;△;)o
by mimiko (2011-03-16 12:36) 

decafish

こちら
http://decafish.blog.so-net.ne.jp/2011-03-05-1
をご利用ください。
by decafish (2011-03-18 18:12) 

L.E.oR.E.o

Yosemiteでも動きますか?
by L.E.oR.E.o (2015-06-12 22:25) 

decafish

チェックしてませんが、10.10でobsoleteなAPIは使っていないので動くと思います。
動かしてみて問題がありましたら、教えていただけると助かります。
よろしくお願いします。
by decafish (2015-06-13 12:37) 

one tskk

リンク壊れとる(
by one tskk (2020-03-03 18:31) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立02/23献立02/24 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。