デーモンプロセスc実装

5582 ワード

デーモンプロセス
デーモンプロセス(Daemon)は、バックグラウンドで実行される特殊なプロセスです.制御端末とは独立して、あるタスクを周期的に実行したり、発生したイベントの処理を待ったりします.デーモンプロセスは有用なプロセスです.Linuxのほとんどのサーバは、インターネットサーバinetd、Webサーバhttpdなど、デーモンプロセスで実現されています.同時に、デーモンプロセスは多くのシステムタスクを完了します.たとえば、ジョブプランニングプロセスcrond、印刷プロセスlpdなどです.
特徴は次のとおりです.
  • バックグラウンドでデーモンを実行する最も重要な特性はバックグラウンドで実行することです.この点、DOSでの常駐メモリプログラムTSRはこれに似ている.
  • は、実行前の環境保護プロセスとは独立して、実行前の環境から分離する必要があります.これらの環境には、閉じていないファイル記述子、制御端末、セッションおよびプロセスグループ、作業ディレクトリ、およびファイル作成マスクなどが含まれます.これらの環境は、通常、保護プロセスが実行する親プロセス(特にshell)から継承されます.
  • 起動方式デーモンプロセスの起動方式には特別な点がある.Linuxシステムの起動時に起動スクリプト/etc/rcから起動できます.dで起動し、ジョブプランニングプロセスcrondで起動してもよいし、ユーザ端末(通常shell)で実行してもよい.これらの特徴を除いて,デーモンプロセスは通常のプロセスとほとんど変わらない.実際,デーモンプロセスを記述することは,上述したデーモンプロセスの特徴に従って1つの一般的なプロセスをデーモンプロセスに改造することである.

  • インプリメンテーション
    protect.c
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define EXEC_FAIL_EXITCODE  110
    
    int main(int argc, char** argv) {
        if (argc < 2) {
            puts("Usage: protect service_process arg...");
            return -10;
        }
    
        // prepare child argv
        char** child_argv = (char**)malloc((argc)*sizeof(char*));
        int i = 1, j = 0;
        for (; i < argc; ++i, ++j) {
            int len = strlen(argv[i]) + 1;
            child_argv[j] = (char*)malloc(len);
            strncpy(child_argv[j], argv[i], len);
        }
        child_argv[argc-1] = NULL;
    
    
        pid_t pid = fork();
        if (pid < 0) {
            puts("fork failed.");
            exit(-20);
        }
    
        if (pid > 0) {
            exit(0); // exit parent process, get rid of terminal
        }
    
        if (pid == 0) {
            setsid(); // create a new session, become process group leader
    
            // nochdir
            // chdir("/");
    
            // noclose
            // close stdin,stdout,stderr
            // for (i = 0; i < 3; ++i) {
            //  close(i);
            // }
    
            for(;;) {
                pid_t pid2 = fork();
                if (pid2 < 0) {
                    exit(-30);
                }
    
                if (pid2 > 0) {
                    int status = 0;
                    waitpid(pid2, &status, 0); // wait service process
                    if (WIFEXITED(status) && WEXITSTATUS(status) == EXEC_FAIL_EXITCODE){
                        exit(-40);
                    }
                }
    
                if (pid2 == 0) {
                    int ret = execvp(argv[1], child_argv); // exec service
                    if (ret < 0) {
                        printf("exec %s failed.
    "
    , argv[1]); exit(EXEC_FAIL_EXITCODE); } } } } return 0; }

    gcc protectをコンパイルする.c -o protect
    実行例:
    ./protect gnome-system-monitor Alt-F 4でウィンドウを閉じてみると、すぐに再起動したことがわかります