Linux学習の概要(15)プロセスグループ、セッション、デーモン

プロセスグループ

  プロセスグループは、ジョブとも呼ばれ、1980年頃にBSDによってUnixに追加された新機能であり、waitpid関数とkill関数のパラメーター内の1つ以上のプロセスのコレクションを表します。各プロセスはプロセスグループに属します。プロセスグループの概念オペレーティングシステムによって設計されたのは、複数のプロセスの管理を簡素化することです。
  親プロセスが子プロセスを作成する場合、デフォルトの子プロセスと親プロセスは同じプロセスグループに属します。プロセスグループID =最初のプロセスID(グループリーダープロセス)であるため、グループリーダープロセスIDはそのプロセスグループと同じです。 ID
  はkill-SIGKILL-プロセスグループID(負)を使用して、プロセスグループ全体のすべてのプロセスを強制終了できます。
  グループリーダープロセスは、プロセスグループを作成し、プロセスグループにプロセスを作成してから終了することができます。プロセスグループにプロセスが存在する限り、リーダープロセスが終了するかどうかに関係なく、プロセスグループは存在します。
  プロセスグループのライフサイクル:プロセスグループは、最後のプロセスが終了する(終了するか、別のプロセスグループに転送される)まで作成されます。
  プロセスは、プロセスグループIDを自分自身またはその子プロセスに設定できます。
  次のコマンドを使用して、プロセスグループIDを表示します。関連情報:

ps ajx

ここに画像の説明を挿入

プロセスグループ関連の機能

現在のプロセスのプロセスグループIDを取得します
 pid_tgetpgrp(void);常に呼び出し元のプロセスグループIDを返します

指定されたプロセスのプロセスグループIDを取得します
 。pid_tgetpgid(pid_t pid);成功:0;失敗:-1、
pid = 0の場合はerrnoを設定し、関数はgetpgrpと同じです。

プロセスが属するプロセスグループの変更は、通常、既存のプロセスグループに参加したり、新しいプロセスグループを作成したりするために使用されます。
int setpgid(pid_t pid、pid_t pgid);成功0、失敗-1
は、パラメーター1に対応するプロセスをパラメーター2に対応するプロセスグループに追加します。
注:
1。子プロセスを新しいグループに変更する場合は、実行する前にフォークする必要があります
。2。権限の問題、非ルートプロセスは、自分で作成した子プロセス、または操作する権限を持つプロセスのみを変更できます。
演習:子プロセスのプロセスグループIDを変更します

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    
    
    pid_t pid;

    if ((pid = fork()) < 0) {
    
    
        perror("fork");
        exit(1);
    } else if (pid == 0) {
    
    
        printf("child PID == %d\n",getpid());
        printf("child Group ID == %d\n",getpgid(0)); // 返回组id
        //printf("child Group ID == %d\n",getpgrp()); // 返回组id
        sleep(7);
        printf("----Group ID of child is changed to %d\n",getpgid(0));
        exit(0);

    } else if (pid > 0) {
    
    
        sleep(1);
        setpgid(pid,pid);           //让子进程自立门户,成为进程组组长,以它的pid为进程组id

        sleep(13);
        printf("\n");
        printf("parent PID == %d\n", getpid());
        printf("parent's parent process PID == %d\n", getppid());
        printf("parent Group ID == %d\n", getpgid(0));

        sleep(5);
        setpgid(getpid(),getppid()); // 改变父进程的组id为父进程的父进程
        printf("\n----Group ID of parent is changed to %d\n",getpgid(0));

        while(1);
    }

    return 0;
}

会話

セッションを作成するには、次の6つの点に注意する必要があり
ます。1。呼び出しプロセスをプロセスグループリーダーにすることはできません。プロセスは、新しいセッションの最初のプロセスになります。
2.プロセスは、新しいプロセスグループのリーダープロセスになります。
3.ルート権限が必要です(ubuntuには必要ありません)
4。新しいセッションは元の制御の中断を破棄し、セッションには制御端末がありません。
5.呼び出しプロセスがグループリーダープロセスの場合、エラーが返さ
れます。6。新しいセッションを確立するときは、最初にforkを呼び出し、親プロセスを終了し、子プロセスがsetsidを呼び出します。

getid関数

プロセスが属するセッションIDを取得します
。pid_tgetsid(pid_t pid);成功した場合は呼び出し元のプロセスのセッションIDを返し、失敗した場合は-1を返します。pid
は0で、現在のプロセスセッションIDを識別します
。psajx:

  • a:現在のユーザーのプロセスを一覧表示するだけでなく、他のすべてのユーザーのプロセスも一覧表示します
  • j:ジョブ制御に関連する情報を一覧表示します
  • x:制御端末があるプロセスだけでなく、制御端末がないプロセスも一覧表示します

リーダープロセスを新しいセッションの最初のプロセスにすることはできません。新しいセッションの最初のプロセスをリーダープロセスにする必要があります。

setsid関数

セッションを作成し、プロセスグループIDを独自のIDで設定します。これは新しいセッションIDでもあります
。pid_tsetsid(void);呼び出し元のプロセスのセッションIDを正常に返し、失敗した場合は-1を返します
。 setsid関数は、新しい社長の新しいリーダーの
演習です。子プロセスをフォークして、新しいセッションを作成します。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    
    
    pid_t pid;

    if ((pid = fork())<0) {
    
    
        perror("fork");
        exit(1);

    } else if (pid == 0) {
    
    

        printf("child process PID is %d\n", getpid());
        printf("Group ID of child is %d\n", getpgid(0));
        printf("Session ID of child is %d\n", getsid(0));

        sleep(10);
        setsid();       //子进程非组长进程,故其成为新会话首进程,且成为组长进程。该进程组id即为会话进程

        printf("Changed:\n");

        printf("child process PID is %d\n", getpid());
        printf("Group ID of child is %d\n", getpgid(0));
        printf("Session ID of child is %d\n", getsid(0));

        sleep(20);

        exit(0);
    }

    return 0;
}

デーモン

  デーモンプロセスは、Linuxのバックグラウンドサービスプロセスです。通常、制御割り込みから独立しており、特定のタスクを定期的に実行するか、特定のイベントの処理を待機します。通常、dで終わる名前を使用します。
  Linuxバックグラウンドの一部のシステムサービスプロセスは、制御の中断がなく、ユーザーと直接対話できず、ユーザーのログインとログアウトの影響を受け入れません。これらは常に実行されています。これらはすべて、次のようなデーモンプロセスです。 -出力メカニズムの読み取りと速度低下、ftpサーバー、nfsサーバーなど。
  デーモンを作成するための最も重要なステップは、setsid関数を呼び出して新しいセッションを作成し、セッションリーダーになることです。

デーモンを作成する

1.子プロセスを作成すると、親プロセスが終了します。
すべての作業は、制御端末から正式に子プロセスで実行され
ます。2。子プロセスで新しいセッションを作成します
。sesid()関数は新しいセッションを作成します。子プロセスが完全に制御不能になっていること
3.現在のディレクトリをルートディレクトリの
chdir()関数に変更して、マウントできないファイルシステムを占有しないようにするか、他のパスに変更し
ます。4。ファイルアクセス許可マスク
umask()関数をにリセットします。
継承されたファイル作成マスクを防ぎ、特定のアクセス許可を拒否します。デーモンの柔軟性を高めます
。5 ファイル記述子を閉じます。
継承された開いているファイルは使用されず、システムリソースを浪費し、アンインストールできません。6
。デーモンの通常のコアの実行を開始します。タスク
。7。デーモンはハンドラーモデルを終了します。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

void daemonize(void)
{
    
    
    pid_t pid;
    /*
     * * 成为一个新会话的首进程,失去控制终端
     * */
    if ((pid = fork()) < 0) {
    
    
        perror("fork");
        exit(1);
    } else if (pid != 0) /* parent */
        exit(0);
    setsid();
    /*
     * * 改变当前工作目录到/目录下.
     * */
    if (chdir("/") < 0) {
    
    
        perror("chdir");
        exit(1);
    }
    /* 设置umask为0 */
    umask(0);
    /*
     * * 重定向0,1,2文件描述符到 /dev/null,因为已经失去控制终端,再操作0,1,2没有意义.
     * */
    close(0);
    open("/dev/null", O_RDWR);
    dup2(0, 1);
    dup2(0, 2);
}

int main(void)
{
    
    
    daemonize();
    while(1); /* 在此循环中可以实现守护进程的核心工作 */
}

おすすめ

転載: blog.csdn.net/bureau123/article/details/112652932