ソケットを介して通信する2つのLinuxシステム(デスクトップおよびARMベースの開発ボード)があります。
サーバーが事前定義された特定のメッセージを送信するときに、開発ボードで実行されているクライアントアプリケーションを再起動(またはリセット)したいと思います。 Linuxを再起動(再起動)したくないので、クライアントアプリケーションが自動的に再起動したいと思います。
どうすればいいのかわかりません。
答え1
/proc/self/exe
特定のメッセージが受信されたらクライアントを実行させます。実行可能ファイルがファイルシステム内の実際にどこにあるかを知る必要はありません。main()
を再利用してargv
新しいパラメータベクトルを設定できます。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char buf[32] = {};
char *exec_argv[] = { argv[0], buf, 0 };
int count = argc > 1 ? atoi(argv[1]) : 0;
printf("Running: %s %d\n", argv[0], count);
snprintf(buf, sizeof(buf), "%d", count+1);
sleep(1);
execv("/proc/self/exe", exec_argv);
/* NOT REACHED */
return 0;
}
これはrestart.c
次のように機能します。
$ gcc restart.c
$ ./a.out 3
Running: ./a.out 3
Running: ./a.out 4
Running: ./a.out 5
答え2
これを行う一般的な方法は、プログラムを終了してから監視システムを使用して再起動することです。これinit
このプログラムは、これらの監視システムを提供します。完全に異なる構成メカニズムを持つさまざまなinitプログラム(SysVinit、BusyBox、Systemdなど)があります(設定ファイルは常に作成されますが、ファイルの場所と構文は異なります)。したがって、使用しているinitプログラムに関するドキュメントを見つけてください。を使用して 。起動時または明示的な要求時にプログラムを起動し、プログラムの終了時に再起動するようにinitを設定します。より高度な監視プログラムがありますが、必ずしも必要とは思えません。このアプローチには、プログラムを自動的に再起動するよりも多くの利点があります。標準なので、プログラムがエラーで終了しても、サービスがどのように作成されたのか気にせずに複数のサービスを再起動できます。
プロセスを終了するように指示する標準的なメカニズムがあります。シグナル。プログラムにTERM信号を送信します。プログラムでクリーンアップを実行する必要がある場合は、シグナルハンドラを作成してください。そのようなコマンドを送信する管理チャネルがある場合は、プログラム固有のコマンドを使用してチャネルを終了できます。
答え3
クライアントアプリケーションがLinuxサービスの場合は、次のコマンドを使用して再起動できます。
service <clientapp> restart
または、構成を強制的に再ロードします。
service <clientapp> reload
service <clientapp> force-reload
カスタムアプリケーションである可能性が高い場合は、信号またはイベントを受信したときに設定を再起動または再ロードする機能をコードに含める必要があります。そうでない場合は、最後の手段としていつでもクライアントアプリケーションを終了できます。
pkill -9 <clientapp>
再起動しましたが、アプリケーションを不確実な状態にしておくので、見苦しいです。
答え4
時にはプロセスが実行されているように見えますが、実際には何もしないことがあります。これは、時に発生するコードのバグが原因で発生する可能性があります。できるだけのことは再起動することです。これは、最初に停止したプロセスを見つけて終了することです。
プロセス(Pythonサーバー)が時々終了せずに停止する問題が発生します。数時間ごとに強制終了/再開して処理します。これはcron
、問題のプログラムを呼び出すスクリプトが独自のプロセスIDを返すのをmyapp.py
奇妙にgrep
妨げるために発生します。grep
#!/bin/sh
# This cron script restarts the server
# Look for a running instance of myapp.py
p=$(ps -eaf | grep "[m]yapp.py")
# Get the second item; the process number
n=$(echo $p | awk '{print $2}')
# If it's not empty, kill the process
if [ "$n" ]
then
kill $n
fi
# Start a new instance
python3 myapp.py