web-dev-qa-db-ja.com

特定/専用のpidに対してのみプロセスを実行する

非常に頻繁に実行したいcプログラムの実行可能ファイルまたはシェルスクリプトがあります。停止/一時停止したり、何かを通知したりする場合は、そのプロセスにシグナルを送信します。したがって、そのプロセスのpidを確認する必要があるたびに、killを使用してシグナルを送信する必要があります。

Pidをチェックする必要があるたびに、システムシャットダウンまでそのことを思い出します。 そのプロセスは特定のpidのみで実行する必要がありますinitのように常に1で実行します。

そのためのC APIはありますか?また、bashプログラムのスクリプトも必要です。

5
gangadhars

PIDを予約したり割り当てたりすることはできないと思います。ただし、次のようなスクリプトでプロセスを開始できます。

_myprocess &
echo "$!" > /tmp/myprocess.pid
_

他の人が参照したように、これは「pidファイル」を作成します。その後、たとえば$(</tmp/myprocess.pid)または$(cat /tmp/myprocess.pid)を使用してbashでフェッチできます。

これを行うときは、プロセスが停止してpidがリサイクルされた場合に、間違ったことを通知することに注意してください。以下で確認できます:

_pid=$(cat /tmp/myprocess.pid)
if [ "$(ps -o comm= -p "$pid")" = "myprocess" ]; then
    ...send your signal...
else echo "Myprocess is dead!"
fi
_

"$(ps -o comm= -p "$pid")"がおかしい場合は、コメントを参照してください。 _/tmp/myprocess.pid_(他のユーザーが書き込みできないようにする必要があります!)の内容を不正に使用する可能性がある場合は、より強力な検証を行うことをお勧めします。

9
goldilocks

Pidを修正することは間違いなく問題の間違った解決策ですが、一部のバージョンのLinuxでは、/proc/sys/kernel/ns_last_pidに値を書き込むことで、希望するpidを取得する可能性が高くなることに注意してください。

echo 9999 | Sudo tee /proc/sys/kernel/ns_last_pid; ps -C ps
9999
  PID TTY          TIME CMD
10000 pts/3    00:00:00 ps

これは、pid 10000がまだ使用されていない場合にのみ機能します(ns_last_pidに書き込んでからプロセス/スレッドを起動するまでの間にpidまたはスレッドの作成が行われていません)。

それ以外の場合は、好きなPIDを取得するまでいつでもフォークできます。

6

通常、実行したい処理と同様の処理は、そのライフサイクルの早い段階で、既知の名前のファイルに独自のpid(getpid(2)を通じて取得可能)を書き込むプロセスによって行われます。一般的に使用されるデーモンでは、このファイルの名前はしばしば構成可能ですが、特殊用途のソフトウェアでは、おそらくそれをハードコーディングすることができます。 (ただし、少なくともマクロを使用することを強くお勧めします。)

PIDファイルは通常/ var/runまたは/ runに配置されますが、/ tmpを含む他の場所に配置することもできます。 Filesystem Hierarchy Standardによる「適切な」場所は/ runですが、/ var/runもかなり使用されており(多くの最新システムでは/ runと同じです)、/ tmpは起動時にroot権限を必要としません(特権を落とす前に、どのシステムデーモンが非常に頻繁に持つか).

次に、そのファイルは、問題のプロセスにシグナルを送信するために、問題のプロセスのPIDを取得するためにさまざまな手段で読み取られます。

3
a CVn

PIDを設定することはできませんが、PGIDを設定することはできますプロセスグループを作成または参加する 。次に、この専用プロセスグループに信号を送信できます。


新しいsystemd initシステムにはこの部分でいくつかの自動化があり、PIDファイルにPIDを書き込み、それを使用して制御するプロセスよりも優れているという印象を受けました。

systemdは、制御されたプロセスを開始する前に(私が理解できるように)「プロセスグループ」に切り替わったようで、すべてがこのグループに含まれています。したがって、特別な「グループ」を覚えておくことで、すべての子プロセスを制御できます。

  • このように機能する場合は、プログラムを変更する必要がないため、PIDを書き出すプロセスよりも優れています。

  • それはまたよりよいかもしれません:

    myprocess&echo $! > /tmp/myprocess.pid

このアプローチは、そのプロセスのすべての子もキャプチャするためです。

私の言葉を裏付ける詳細なドキュメントは手元にありませんが、 heresystemdがcgroupsから必要とするものの一般的な考え方であり、これは私の印象に合わせる:

コントロールグループは2つあります:(A)プロセスを階層的にグループ化およびラベル付けする方法、および(B)これらのグループにリソース制限を適用する方法。 systemdは前者(A)のみを必要とし、後者(B)は必要としません。つまり、コントロールグループのリソースコントローラーなしでカーネルをコンパイルでき(B)、systemdは完全に動作します。ただし、さらにグループ化機能を完全に無効にすると(A)、systemdは起動時に大声で不平を言い、大きな警告を出して不本意ながら続行します。機能制限モード。

システムレベルのデーモンは、起動時の起動シーケンスに従って割り当てられます。固定pidを特定のプロセスに割り当てることは、システムの負荷やその他の依存関係に従ってカーネルによって割り当てられるため、不可能であると思います。

しかし、システムコールを使用して、固定PIDをプロセスに割り当てることができます。しかし、それをどのようにして実現できるかはわかりません。

0
dina3e