Linux のデーモン: 単純なデーモンの作成方法と使用方法
デーモン プロセスは、Linux システムの特別なプロセスです。制御端末なしでバックグラウンドで実行され、ユーザーの介入を受けません。システムまたはアプリケーション関連のタスクと機能の実行を担当します。デーモンの役割は、予期せぬ事故や異常に対処するためにシステムの安定性と効率を向上させることです。組み込み Linux デバイスでは、デーモン プロセスを使用してシステムのメイン プロセスを保護し、システムが完全にクラッシュしてユーザー エクスペリエンスが損なわれる原因となる異常終了を防ぐことができます。しかし、Linux 上のデーモン プロセスを本当に理解していますか? Linux で簡単なデーモンを作成して使用する方法をご存知ですか?この記事では、Linux でのデーモン プロセスの関連知識を詳しく紹介し、Linux でこの強力なプロセス タイプをよりよく使用し、理解できるようにします。
Linux デバイスにデーモン プロセスを作成して、システムのメイン プロセスを保護し、予期せぬ事故によってメイン プロセスが異常終了し、応答なしにシステムが完全にシャットダウンしてユーザー エクスペリエンスが破壊されることを防ぎます。しかし、多くの情報を検討した結果、ほとんどの人は x86 プラットフォームでデーモン プロセスを作成して実装する方法についてのみ話しており、組み込みプラットフォームでデーモン プロセスを作成して実装する方法を紹介する人は誰もいなかったことがわかりました。そこで、いくつかの探索を行い、原理からコードに至るまでのすべてを一般的に理解した後、私自身でいくつかのアイデアを思いつきました。以下に簡単な概要と構成を示します。
1. 技術原則
以下は、x86 Linux システムのデーモン プロセスの紹介と説明に関するインターネットからの抜粋です。
Daemon はバックグラウンドで実行される特別なプロセスであり、制御端末から独立しており、定期的に特定のタスクを実行したり、特定のイベントの処理を待機したりします。
デーモン プロセスは特殊な孤立プロセスです。この種のプロセスは端末から分離されています。なぜ端末から分離する必要があるのでしょうか?端末から切り離しているのは、端末が生成する情報によって処理が中断されることを防ぐためであり、実行中の情報はどの端末にも表示されません。 Linux では、各システムがユーザーと通信するためのインターフェースをターミナルと呼ぶため、このターミナルから実行を開始するすべてのプロセスはこのターミナルに接続されます。このターミナルは、これらのプロセスの制御ターミナルと呼ばれます。 , 該当するプロセスが自動的に終了します。ただし、デーモン プロセスはこの制限を突破することができます。デーモン プロセスはターミナルから切り離され、バックグラウンドで実行されます。ターミナルから切り離される目的は、実行中のプロセス中の情報がターミナルに表示されないようにするためです。どの端末からもアクセスできません。生成された端末メッセージによって中断されます。実行されると実行を開始し、システム全体がシャットダウンされるまで終了しません (もちろん、対応するデーモン プロセスを強制終了すると考えることもできます)。プロセスがユーザー、中断、その他の変更の影響を受けないようにする場合は、このプロセスをデーモン プロセスに変える必要があります。
2. 設計手順
x86 プラットフォーム上の Linux システムの場合、理論的には、上記の効果を実現するために、デーモン プロセスには厳密な実装手順が必要です。つまり、デーモン プロセスは、他のタスクの干渉や影響を受けることなくバックグラウンドで安定して実行できるように、起動の開始時にシステム関連の制限をいくつか削除する必要があります。
x86 プラットフォームでデーモンを作成する基本的なプロセスは次のとおりです:
- 端末の動作を制御する一部の信号をブロックします。これは、制御端末が妨害されて、デーモンが実行される前に終了したりハングしたりするのを防ぐためです。信号の使用方法の詳細については、「信号割り込みの処理」を参照してください。
- バックグラウンドで実行されます。これは、制御端末のハングを避けるためにデーモン プロセスをバックグラウンドに置くためです。その方法は、プロセス内で fork() を呼び出して親プロセスを終了し、子プロセスのバックグラウンドでデーモンを実行させることです。
- 端末、ログインセッション、プロセスグループの制御を切り離します。まず、Linux におけるプロセスと制御端末、ログイン セッションとプロセス グループの関係を紹介する必要があります。プロセスはプロセス グループに属し、プロセス グループ番号 (GID) はプロセス グループ リーダーのプロセス番号 (PID) です。 。ログイン セッションには複数のプロセス グループを含めることができます。これらのプロセス グループは制御端末を共有します。この制御端末は通常、プロセスの作成元となったシェル ログイン端末です。制御端末、ログイン セッション、プロセス グループは通常、親プロセスから継承されます。私たちの目標は、それらを排除し、それらの影響を受けないようにすることです。したがって、子に新しいセッション リーダーを処理させるには、setsid() を呼び出す必要があります。 etsid() 呼び出しが成功すると、プロセスは新しいセッション グループ リーダーおよび新しいプロセス グループ リーダーになり、元のログイン セッションおよびプロセス グループから分離されます。セッションプロセスは制御端末への排他性があるため、同時にプロセスは制御端末から切り離されます。
- プロセスが制御端末を再度オープンしないようにします。現在、プロセスはターミナルレス セッション リーダーになっていますが、制御ターミナルを開くために再適用できます。子プロセスを再度作成することで、プロセスがセッション リーダーでなくなることで、制御ターミナルを再度開くことを防ぐことができます。
- 開いているファイル記述子を閉じます。プロセスは、そのプロセスを作成した親プロセスからオープン ファイル記述子を継承します。閉じていない場合、システム リソースが無駄になり、プロセスが存在するファイル システムをアンマウントできなくなり、予期しないエラーが発生します。
- 現在の作業ディレクトリを変更します。プロセスがアクティブな間は、その作業ディレクトリを含むファイル システムをマウント解除することはできません。通常、作業ディレクトリをルート ディレクトリに変更する必要があります。実行する必要があるコア ダンプの場合、実行ログを書き込むプロセスにより、作業ディレクトリが /tmp などの特定のディレクトリに変更されます。
- ファイル作成マスクをリセットします。プロセスは、それを作成した親プロセスからファイル作成マスクを継承します。デーモンによって作成されたファイルのアクセス許可が変更される可能性があります。これを防ぐには、ファイル作成マスクをクリアする必要があります。
- SIGCHLD シグナルを処理します。一部のプロセス、特にサーバー プロセスでは、リクエストが到着したときにリクエストを処理するために子プロセスが生成されることがよくあります。親プロセスが子プロセスの終了を待たない場合、子プロセスはゾンビ プロセス (ゾンビ) となり、システム リソースを占有します (ゾンビ プロセスの詳細については、「ゾンビ プロセス」を参照してください)。親プロセスが子プロセスの終了を待機すると、親プロセスの負担が増加し、サーバー プロセスの同時実行パフォーマンスに影響します。 Linux では、SIGCHLD 信号の動作を SIG_IGN に設定するだけで済みます。このようにして、カーネルは子プロセスが終了するまでゾンビ プロセスを生成しません。
–
以下は、先輩のブログから抜粋したソース コードの完全なセットです:
3. 実際の状況
上記のプロセス ロジックと実際のコードから、x86 プラットフォームのデーモン プロセスは実際には非常に複雑で、多くの面倒な初期化プロセスが必要であることがわかります。しかし、組み込みプラットフォームの場合、そのような複雑な処理はなく、プロセスはより単純になるようです。なぜなら、この組み込みシステムではデーモンプロセスが有効になっているからです。このデーモンプロセスを利用して別のデーモン化プロセスを起動し、そのプロセスが正常に動作しているかを定期的に監視し、異常動作を発見した場合には直ちにプロセスを再起動することが目的です。
そこで、上記のプロセスを簡略化し、次のプロセスを得ました:
- デーモンプロセスで監視が必要なプロセスを起動します。
- デーモン プロセスにスレッドを作成して、デーモン プロセスの実行ステータスを定期的に監視します。
- デーモンプロセスは、デーモン化されたプロセスが正常に動作しているかどうかを判断し、異常な動作を検出すると、直ちにプロセスを再起動します。
– 4. 実際のソースコード
以下は、この組み込みシステム プロジェクトで設計されたデーモン プロセス モジュールの完全なコードです。
/****************************************************************************************** ******** ** 函数名称: lockfile ** 功能描述: 对文件加锁/解锁 ** 输入参数: lock: 1表示进行加锁处理, 0表示进行解锁处理 ** 输出参数: 无 ** 返回参 数: 无 ************************************************************************************* *************/ int tryto_lockfile(int fd, int lock) { struct flock fl; fl.l_type = (lock = = 1) ? F_WRLCK : F_UNLCK; fl.l_start = 0; fl.l_whence = SEEK_SET; fl.l_len = 0; return (f cntl(fd, F_SETLK, &fl)); } /*************************************************************** *********************************** ** 函数名称: get_proc_running_state ** 功能描述: 获取进程 运行状态 ** 输入参数: 无 ** 输出参数: 无 ** 返回参数: 返回-1表示路径错误 ** 返回参数: 返回0表示进程 从未运行过,返回1表示进程曾经运行过但是现在停止运行了,返回2表示进程正在运行 中 **************************************************************************************** **********/ static int get_proc_running_state(const char* filename) { int fd; if (filename == NULL) { /* 文件名为 空 */ return -1; } fd = open(filename, O_RDWR, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); i f (fd 0) { /* 文件不存在,表示进程从未运行 过 */ return 0; } if (tryto_lockfile(fd, 1) == -1) { /* 文件加锁失败,表示进程在运行 中 */ close(fd); return 2; } else { /* 文件加锁成功,表示进程已经消 失 */ tryto_lockfile(fd, 0); /* 此处要注意记得解锁和关闭文 件 */ close(fd); return 1; } } /*********************************************************** *************************************** ** 函数名称: proc_watch ** 功能描述: 检测进程是否有在运 行,没有运行则重新启动之 ** 输入参数: procname: 进程名 ** 输出参数: 无 ** 返回参数: 返回-1表示进程从 未运行过;返回0表示进程当前运行正常; ** 返回参数: 返回其他非零值表示进程不存在且已被重新启动,返回的值 是新的pid值 *************************************************************************** ***********************/ int proc_watch(const char *procname) { int result, state; char fi lename[100]; result = 0; sprintf(filename, "/var/run/%s.pid", procname); state = get_proc_ running_state(filename); switch (state) { case 0: result = -1; break; case 1: result = sta rt_proc_by_name(procname); break; case 2: result = 0; break; default: break; } return resu lt; } /************************************************************************************ ************** ** 函数名称: start_proc ** 功能描述: 启动进程开始运行 ** 输入参数: 无 ** 输出参 数: 无 ** 返回参数: 进程的ID号,若启动失败则返回 0 ***************************************************************************************** *********/ int start_proc_by_name(const char* procname) { pid_t pid, child_pid; char filen ame[100]; sprintf(filename, "%s%s", PROC_FILE_PATH, procname); child_pid = 0; if (access(f ilename, X_OK | F_OK) != 0) { /* 如果文件存在,并且可执行 */ return 0; } pid = fork(); /* 首 先要fork一个进程出来 */ if (pid 0) { /* 创建进程失 败 */ return 0; } else if (pid == 0) { /* 创建进程成功,此处是子进程的代 码 */ if (execl(filename, procname, (char *)NULL) != -1) { return 1; } else { return 0; } } else { /* 创建进程成功,此处是父进程代 ******************************************************************* ** 函数名 称: thread_client_hdl ** 功能描述: client进程监视线程 ** 输入参数: 无 ** 输出参数: 无 ** 返回参 数: 无 ************************************************************************************* *************/ static void *thread_client_hdl(void *pdata) { int result; pdata = pdata; sl eep(10); /* 第一次要进行延 时 */ for (;;) { printf("time to check thread_client...\n"); result = proc_watch(PROC_NAME _CLIENT); if (result == -1) { printf("thread_client never exist...\n"); } else if (result == 0) { printf("thread_client running ok...\n"); } else { printf("thread_client has gone! but restarted...\n"); } sleep(10); } return NULL; } /************************************* ************************************************************* ** 函数名称: main ** 功能描 述: 入口主函数 ** 输入参数: 无 ** 输出参数: 无 ** 返回参 数: 无 ************************************************************************************* *************/ int main(int argc, char *argv[]) { int client_para; char *p, *process_name; pthread_t thread_client; process_name = argv[0]; /* 获取进程名 称 */ p = process_name + strlen(process_name); while (*p != '/' && p != process_name) { p- -; } if (*p == '/') { process_name = p + 1; } printf("\"%s\" starting...\n", process_name) ; client_para = 0x01; if (pthread_create(&thread_client, NULL, thread_client_hdl, &client_ para) != 0) { printf("create thread_client failed!\n"); return 1; } if (start_proc_by_name (PROC_NAME_CLIENT) == 0) { printf("start thread_client failed!\n"); return 1; } for (;;) { sleep(60); printf("i am still alive...\n"); } return 0; }
通过本文,你应该对 Linux 下的守护进程有了一个基本的了解,知道了它的定义、特点和用途。你也应该明白了如何在 Linux 下编写和使用简单的守护进程,以及使用守护进程时需要注意的一些问题和技巧。我们建议你在使用 Linux 系统时,使用守护进程来提高系统的稳定性和效率。同时,我们也提醒你在使用守护进程时要注意一些潜在的问题和挑战,如信号处理、日志记录、资源管理等。希望本文能够帮助你更好地使用 Linux 系统,让你在 Linux 下掌握守护进程的编写和使用。
以上がLinux のデーモン: 単純なデーモンの作成方法と使用方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

Linuxシステム管理者の主なタスクには、システムの監視とパフォーマンスチューニング、ユーザー管理、ソフトウェアパッケージ管理、セキュリティ管理とバックアップ、トラブルシューティングと解像度、パフォーマンスの最適化、ベストプラクティスが含まれます。 1. TOP、HTOP、その他のツールを使用して、システムのパフォーマンスを監視し、チューニングします。 2。ユーザーADDコマンドおよびその他のコマンドを介して、ユーザーアカウントとアクセス許可を管理します。 3. APTとYUMを使用してソフトウェアパッケージを管理し、システムの更新とセキュリティを確保します。 4.ファイアウォールを構成し、ログを監視し、データバックアップを実行して、システムセキュリティを確保します。 5.ログ分析とツールの使用を通じてトラブルシューティングと解決。 6.カーネルパラメーターとアプリケーションの構成を最適化し、ベストプラクティスに従ってシステムのパフォーマンスと安定性を向上させます。

Linuxの学習は難しくありません。 1.Linuxは、UNIXに基づいたオープンソースオペレーティングシステムであり、サーバー、組み込みシステム、およびパーソナルコンピューターで広く使用されています。 2。ファイルシステムと許可管理を理解することが重要です。ファイルシステムは階層的であり、許可には読み取り、書き込み、実行が含まれます。 3。APTやDNFなどのパッケージ管理システムは、ソフトウェア管理を便利にします。 4。プロセス管理は、PSおよびTOPコマンドを通じて実装されます。 5. MKDIR、CD、Touch、Nanoなどの基本的なコマンドから学習を開始し、シェルスクリプトやテキスト処理などの高度な使用法を試してください。 6.許可問題などの一般的なエラーは、SudoとChmodを通じて解決できます。 7.パフォーマンスの最適化の提案には、HTOPを使用してリソースを監視すること、不要なファイルのクリーニング、SYの使用が含まれます

Linux管理者の平均年salは、米国で75,000〜95,000ドル、ヨーロッパでは40,000〜60,000ユーロです。給与を増やすには、次のことができます。1。クラウドコンピューティングやコンテナテクノロジーなどの新しいテクノロジーを継続的に学習します。 2。プロジェクトの経験を蓄積し、ポートフォリオを確立します。 3.プロフェッショナルネットワークを確立し、ネットワークを拡大します。

Linuxの主な用途には、1。Serverオペレーティングシステム、2。EmbeddedSystem、3。Desktopオペレーティングシステム、4。開発およびテスト環境。 Linuxはこれらの分野で優れており、安定性、セキュリティ、効率的な開発ツールを提供します。

インターネットは単一のオペレーティングシステムに依存していませんが、Linuxはその上で重要な役割を果たしています。 Linuxは、サーバーやネットワークデバイスで広く使用されており、安定性、セキュリティ、スケーラビリティに人気があります。

Linuxオペレーティングシステムのコアは、コマンドラインインターフェイスで、コマンドラインを介してさまざまな操作を実行できます。 1.ファイルおよびディレクトリ操作は、ファイルとディレクトリを管理するために、LS、CD、MKDIR、RM、その他のコマンドを使用します。 2。ユーザーおよび許可管理は、useradd、passwd、chmod、その他のコマンドを介してシステムのセキュリティとリソースの割り当てを保証します。 3。プロセス管理は、PS、Kill、およびその他のコマンドを使用して、システムプロセスを監視および制御します。 4。ネットワーク操作には、Ping、Ifconfig、SSH、およびネットワーク接続を構成および管理するためのその他のコマンドが含まれます。 5.システムの監視とメンテナンスは、TOP、DF、DUなどのコマンドを使用して、システムの動作ステータスとリソースの使用を理解します。

導入 Linuxは、柔軟性と効率性により、開発者、システム管理者、およびパワーユーザーが好む強力なオペレーティングシステムです。しかし、頻繁に長く複雑なコマンドを使用することは退屈でERです

Linuxは、サーバー、開発環境、埋め込みシステムに適しています。 1.サーバーオペレーティングシステムとして、Linuxは安定して効率的であり、多くの場合、高電流アプリケーションの展開に使用されます。 2。開発環境として、Linuxは効率的なコマンドラインツールとパッケージ管理システムを提供して、開発効率を向上させます。 3.埋め込まれたシステムでは、Linuxは軽量でカスタマイズ可能で、リソースが限られている環境に適しています。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

Dreamweaver Mac版
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

WebStorm Mac版
便利なJavaScript開発ツール
