Linuxのプロセス管理とタスクのスケジューリング

Linuxのプロセス管理とタスクのスケジューリング

1. プロセス関連の概念の紹介

1. オペレーティング システム カーネルの役割

1.1 オペレーティングシステム

  • オペレーティング システムには、一般に次の 2 つの意味があります。

    • コンピュータ リソースを管理するためのコア ソフトウェアと、コマンド ライン インタープリタ、 GUI ユーザー グラフィカル インターフェイス、ファイル ツール、テキスト エディタなどの付属の標準ソフトウェア ツールが含まれていることを示します。
    • 狭義には、コンピュータリソースを管理し、割り当てるコアソフトウェアのみを指します。(CPU 管理、RAM メモリ管理、デバイス管理などのコンピューター リソースの管理
      )
  • ほとんどの人が使用するオペレーティング システムという用語は、一般に、それに付属する標準ソフトウェアを含む最初の意味を指します。

1.2 カーネル

  • カーネルは、一般に、コンピュータ リソースを管理し、割り当てるコア ソフトウェアのみを意味すると考えられています。これはオペレーティング システムの中核部分です。
  • カーネルは主に次のタスクを担当します。
カーネル関数 説明する
プロセスのスケジューリング 今日のコンピューターには通常、プログラム命令の実行に使用される複数の物理コアがあります。Linux システムはプリエンプティブ マルチタスク オペレーティング システムです。マルチタスクとは、複数のプロセスが同時にメモリ内に常駐して CPU によって処理されることを意味します。プリエンプティブとは、どのプロセスが CPU を使用するか、またはどれだけの時間 CPU を使用するかを意味します。ルールは、 CPU 自体がどのプロセスを処理するかを決定するのではなく、カーネル プロセス スケジューラ
メモリ管理 現在、メモリはますます大きくなっていますが、ソフトウェアの量も増加しています。コンピュータの物理メモリは依然として比較的希少なリソースであるため、カーネルはメモリを合理的に管理し、システムの各プロセスにメモリを割り当てる必要があります。
ファイルシステム機能を提供します カーネルはディスク上に特別なファイルシステムを作成して、ファイルの作成、複製、更新、削除などを行うことができます。
プロセスの作成と破棄 カーネルはプログラムをメモリにロードし、実行に必要なリソース (CPU、メモリ、ファイルへのアクセスなど) を割り当てることができます。メモリ内で実行されるプログラムのインスタンスはプロセスと呼ばれます。プログラムがカーネルによって破棄されるか、プログラム自体が実行される場合、カーネルは、プログラムが使用していたリソースが後続のプロセスで再利用できるように解放されることを保証する必要もあります。
アクセスデバイス コンピュータに接続されているデバイス (マイク、モニタ、キーボードとマウス、ディスクとテープ、フロッピー ディスクなど) は、コンピュータとコンピュータおよび外部世界との間で情報を交換し、コンピュータが入力や入力などの操作を実行できるようにします。出力。カーネルは、各上位層アプリケーションがデバイスにアクセスするための標準インターフェイスを提供し、同時に複数のプロセスによるデバイスへのアクセスを調停します。
ネットワーク機能を提供する カーネルは、ユーザー プロセスに代わってネットワーク データを送受信します。
システムコールアプリケーションプログラミングインターフェースを提供します プロセスは、システム コールであるエントリを通じてカーネルにさまざまな操作を完了するよう要求できます。
仮想 PC の抽象化を提供します Linux システムでは、複数のユーザーが同時にシステムにログインし、異なる操作を実行できます。カーネルは、各ユーザーの操作とデバイスの使用を確実に分離するための抽象化レイヤーを提供します。

2. 手順は?プロセス?糸?

プログラム、プロセス、スレッド
プログラム 一般的なプログラムは、ソース コードの形式とバイナリ実行可能プログラムの形式の 2 つの形式で存在します。ソース コードは人間が読めるテキスト (C などの言語で書かれた一連のステートメント) です。CPU で実行するには、プログラムをコンパイルして、コンピュータが認識できるバイナリ マシン コード命令 (Windows の .exe ファイル、Linux の .o ファイルなど) にリンクする必要があります。この 2 つは同義語とみなされ、両方ともプログラムを表します。 。
プロセス 簡単に言えば、プロセスは実行中のプログラムのインスタンスです。プログラムが実行されると、カーネルはプログラムの命令をメモリにロードし、メモリ空間をプログラム変数に割り当て、プロセスの情報を記録するために対応するデータ構造を設定します (Linux カーネルによるこのデータ構造の実装は と呼ばれます)。タスク リスト、プロセス ID、終了ステータス、ユーザーおよびグループ ID などを保持します)。したがって、プロセスは、実行中のプログラムとそれに含まれるデータおよび操作として説明することもできます。
最新の UNIX 実装では、各プロセスで複数のスレッドを実行できます。スレッドを理解するためのより適切な表現は、同じメモリ空間やその他の属性を共有する軽量プロセスのコレクションです。各スレッドは同じコード ブロックを実行し、同じデータ領域とヒープを共有します。ただし、各スレッドには独自のスタック領域 (ローカル変数および関数呼び出し接続情報を含む) があります。スレッドは共有グローバル変数を介して通信でき、プロセスは IPC および同期メカニズムを介して通信することもできます。
  • プロセスアイコン

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-V7xnd5CT-1691714290367)(png/process icon.png)]

3. Linux のプロセス

  • task struct: プロセス情報を格納する Linux カーネルのデータ構造形式

  • タスク リスト: 複数のタスクのタスク構造体のリンクされたリスト

  • Linuxプロセスの作成

    • init: 最初のプロセスはシステムの起動時に作成される最も重要なプロセスであり、そのプロセス ID は 1 です。
    • init を除くその他のプロセス: すべては、fork() システム コールを使用して親プロセスによって作成されます。
  • スレッドの表示: cat /proc/PID/status |grep -i スレッド

  • ページ フレーム: ページ フレーム、ページ データの保存、ページ 4k の保存に使用されます。

  • 物理アドレス空間とリニアアドレス空間

  • MMU: メモリ管理ユニットは、リニア アドレスと物理アドレス ハードウェアの変換を担当します。

  • TLB: Translation Lookaside Buffer Translation Lookaside Buffer
    物理ページに素早くアクセスするために、仮想アドレスと物理アドレス間のマッピング関係を保存するキャッシュ。

3. ユーザーモードとカーネルモードの概念


  • 最新のプロセッサ アーキテクチャでは、通常、CPU がユーザー モード (ユーザー モード) とカーネル モード(カーネル モード: カーネル モードは監視モードと呼ばれることもあります) という少なくとも 2 つの異なるモードで実行でき、モード間で切り替えることができます。
    同様に、仮想メモリの特定の部分がユーザー空間またはカーネル空間としてマークされる場合があります。ユーザー モードでプロセスを実行する場合
    、CPU はユーザー制御としてマークされたメモリ領域にのみアクセスでき、カーネル領域としてマークされたメモリにアクセスしようとすると
    ハードウェア例外が発生します。

  • ユーザー空間とカーネル空間

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-xpclw7Lq-1691714290368)(png/2019-10-27-17-08-26) .png)]

  • ユーザーモードとカーネルモードの簡単な比較
ユーザーモード カーネルモード
シャットダウンコマンドを実行できません shutdown コマンドを実行して現在のシステムをシャットダウンします。
メモリ管理ハードウェアにアクセスできない メモリ管理のためにハードウェアにアクセスできる
できない デバイス I/O 操作の開始
できない 最も特権のある命令を実行する

4. プロセスの状態と状態間の遷移

  • プロセスのライフサイクル全体で、作成、実行、ブロック、準備完了、終了の状態が渡されることがあります。
  • 回路図は以下の通りです:

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-Uo8v72nn-1691714290368)(png/プロセス状態遷移.png)]

  • 各ステータスの説明
作成ステータス プロセスを作成するときは、空白の PCB (プロセス コントロール ブロック プロセス コントロール ブロック) を申請し、プロセスを制御および管理するための情報を入力し、リソースの割り当てを完了する必要があります。リソースを満たせない、実行をスケジュールできないなど、作成作業を完了できない場合、この時点でのプロセスの状態を作成状態と呼びます。
準備完了状態 プロセスの準備が完了し、必要なリソースが割り当てられ、CPU が割り当てられるとすぐに実行できるようになります。
実行状態 プロセスが準備完了状態でスケジュールされた後、プロセスは実行状態に入ります。
ブロックされた状態 実行中のプロセスは、何らかのイベント (I/O 要求、バッファーの適用の失敗) により一時的に実行できなくなり、プロセスはブロックされます。リクエストが満たされると、システムコールを待機する準備完了状態に入ります。
終了状態 プロセスが終了するか、エラーが発生するか、システムによって終了され、終了状態になります。もう実行できません
  • 状態間の遷移の 4 つのケース
準備が整うまで走っている 1. 主な理由は、プロセスが長時間 CPU を占有し、システムによってプロセスに割り当てられる時間が制限されていることです。 2. プリエンプティブ優先スケジューリング アルゴリズムを使用しているシステムで、実行する優先度の高いプロセスがある場合の場合、プロセスは強制的に CPU を放棄し、プロセスは実行状態から準備完了状態に変わります。
実行する準備ができています 実行中のプロセスのタイム スライスが使い果たされると、スケジューリングは準備完了キューに移動し、適切なプロセスを選択して CPU を割り当てます。
ブロックするために走る 実行中のプロセスがイベント待ちにより実行できない場合、プロセスは実行状態から閉塞状態に遷移します。
準備完了までブロックする プロセスが待っているイベントが発生すると、準備完了キューに入ります。

5. Linux プロセスのステータス

  • Linux プロセスの種類:
    デーモン: デーモン、システムのブート プロセス中に開始されるプロセスであり、端末プロセスとは関係ありません。 フォアグラウンド プロセス
    : 端末に関連し、端末を通じて開始されるプロセス
    注: この 2 つは相互に変換できます。

  • linux 进程状态:
    运行态:running
    就绪态:ready
    睡眠态:
    可中断睡眠态:interruptable
    不可中断睡眠态:uninterruptable
    停止态:stopped,暂停于内存,但不会被调度,除非手动启动
    僵死态:zombie,结束进程,父进程结束前,子进程不关闭

6.Linux 的进程优先级

  • centos 进程优先级

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-35sAbERp-1691714290368)(png/2019-10-27-17-11-36.png)]

  • 系统优先级:数字越小,优先级越高
  • 0-139:每个优先级有 140 个运行队列和过期队列
  • 实时优先级: 99-0 值最大优先级最高
  • nice 值:-20 到 19,对应系统优先级 100-139

6.进程间通信 IPC

  • IPC 进程间通信(Inter Process Communication)
  • 同一主机:pipe
管道
    socket   套接字文件
    signal   信号
    shm
shared memory
    semaphore
信号量,一种计数器
  • 不同主机:socket IP 和端口号
    RPC
    remote procedure call
    MQ
消息队列,如:Kafka,RabbitMQ,ActiveMQ

二.Linux 下进程相关的工具介绍

1.pstree 命令

  • patree 命令以树状结构显示当前系统进程

  • 用法

SYNOPSIS
       pstree [-a, --arguments] [-c, --compact] [-h, --highlight-all, -Hpid, --high‐
       light-pid pid] [-g] --show-pgids] [-l, --long] [-n, --numeric-sort]
       [-N, --ns-sortns [-p, --show-pids] [-s, --show-parents] [-S, --ns-changes]
       [-t, --thread-names] [-T, --hide-threads] [-u, --uid-changes] [-Z, --security-con‐
       text] [-A, --ascii, -G, --vt100, -U, --unicode] [pid, user]
       pstree -V, --version
    -p 显示每个进程的进程ID
    -a 显示进程关联的命令及其所附带的运行参数,如例1
    -A 使用ASCII码值画出树干,显示内容不变
    -c 禁用相同的子进程折叠,pstree显示时默认折叠子进程
    -h 高亮显示当前进程和其父进程,如果终端不支持高亮则不作任何操作,如例2
    -H 高亮所指定的进程号所代表的进程,如果使用该选项而未指定pid,则pstree执行失败,如例3
    -g 显示进程组ID号(PGID),如果PID也指定,那就先显示进程PID,格式(PID,PGID)
    -l 使用长格式
    -n 将同一个父进程的子进程按照进程ID大小从小到大排序显示
    -s 显示所指定的进程的父进程,如例4
    -t 如果可行就显示每个进程的线程全名,pstree默认将线程放在[{
    
    ...}]内。
    -T 只显示进程,忽略线程
  • 例 1
[root@centos8 ~]#pstree -a
systemd --switched-root --system --deserialize 17
  ├─ModemManager
  │   └─2*[{
    
    ModemManager}]
  ├─NetworkManager --no-daemon
  │   └─2*[{
    
    NetworkManager}]
  ├─VGAuthService -s
  ├─abrt-dbus -t133
  │   └─2*[{
    
    abrt-dbus}]
  ├─abrt-dump-journ -fxtD
  ├─abrt-dump-journ -fxtD
  ├─abrtd -d -s
  │   └─2*[{
    
    abrtd}]
  ├─accounts-daemon
  │   └─2*[{
    
    accounts-daemon}]
  ├─alsactl -s -n 19 -c -E ALSA_CONFIG_PATH=/etc/alsa/alsactl.conf--initfile=/lib/als
  ├─atd -f
  ...
[root@centos8 ~]#pstree
systemd─┬─ModemManager───2*[{
    
    ModemManager}]
        ├─NetworkManager───2*[{
    
    NetworkManager}]
        ├─VGAuthService
        ├─abrt-dbus───2*[{
    
    abrt-dbus}]
        ├─2*[abrt-dump-journ]
        ├─abrtd───2*[{
    
    abrtd}]
        ├─accounts-daemon───2*[{
    
    accounts-daemon}]
        ├─alsactl
        ├─atd
        ├─auditd─┬─sedispatch
        │        └─2*[{
    
    auditd}]
  • 例 2
[root@centos8 ~]#pstree -ha
...
├─systemd-udevd
  ├─tmux: server new -s class    # 高亮
  │   ├─bash
  │   │   └─man pstree
  │   │       └─less
  │   ├─bash
  │   │   └─ssh 172.20.3.82
  │   └─bash                    # 高亮
  │       └─pstree -ha          # 高亮
  ...
  • 例 3
[root@centos8 ~]#pstree -H48708 -p
      ...
      ├─systemd-udevd(668)
           ├─`tmux: server(48708)`─┬─bash(48709)───man(49846)───less(49858)      # 反引号内的进程高亮
           │                       ├─bash(48744)───ssh(48782)
           │                       └─bash(49899)───pstree(49980)
           ...
  • 例 4
[root@centos8 ~]#pstree -s 1316 -p
systemd(1)───tuned(1022)───{
    
    tuned}(1316)

2.ps 命令

  • ps 是 linux 系统中查看进程的有力工具之一。man 帮助指明其用于报告当前系统所有进程的一个快照
  • ps 支持多种风格的命令选项
    • UNIX 选项 如-A -e
    • BSD 选项 如 a
    • GNU 选项 如–help
  • ps 用法:不带选项默认显示当前终端中的进程
BSD风格:
    a 选项包括所有终端中的进程
    x 选项包括不链接终端的进程
    u 选项显示进程所有者的信息
    f 选项显示进程树,相当于 --forest
    k|--sort  属性 对属性排序,属性前加- 表示倒序
    o 属性… 选项显示定制的信息 pid、cmd、%cpu、%mem、ni、pri、rtpri、psr(CPU编号)
    L 显示支持的属性列表
UNIX风格选项:
    -C cmdlist 指定命令,多个命令用,分隔
    -L 显示线程
    -e 显示所有进程,相当于-A
    -f 显示完整格式程序信息
    -F 显示更完整格式的进程信息
    -H 以进程层级格式显示进程相关信息
    -u userlist  指定有效的用户ID或名称
    -U userlist 指定真正的用户ID或名称
    -g gid或groupname  指定有效的gid或组名称
    -G gid或groupname  指定真正的gid或组名称
    -p pid 显示指pid的进程
    --ppid pid  显示属于pid的子进程
    -t  ttylist  指定tty,相当于 t
    -M  显示SELinux信息,相当于Z
  • 值得注意的是,下面的两个命令是不一样的,虽然其结果表现的几乎一样:

ps -aux
ps aux

  • POSIX 和 unix 标准需要使用-aux选项来指明所有属于用户x的进程。而 BSD 风格的x选项指明包括不链接终
    端的进程,如下面的例子:
ps -auroot              # 该命令将会列出所有属于root用户的进程

ps auroot               # 该命令出错
  • ps 输出选项参数介绍
[root@centos8 ~]#ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.5 242356  8332 ?        Ss   00:58   0:07 /usr/lib/systemd/systemd --switched-root --system --deserial
root          2  0.0  0.0      0     0 ?        S    00:58   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        I<   00:58   0:00 [rcu_gp]
root          4  0.0  0.0      0     0 ?        I<   00:58   0:00 [rcu_par_gp]
root          6  0.0  0.0      0     0 ?        I<   00:58   0:00 [kworker/0:0H-xfs-log/nvme0n1p2]
root          8  0.0  0.0      0     0 ?        I<   00:58   0:00 [mm_percpu_wq]
root          9  0.0  0.0      0     0 ?        S    00:58   0:00 [ksoftirqd/0]
...
VSZ Virtual memory SiZe,虚拟内存集,线性内存
RSS ReSident Size, 常驻内存集
TTY 该进程所依附的终端
STAT 进程状态
START 进程启动的时间(HH:MM)或日期
TIME 累计的 CPU 时间
%CPU (cputime/realtime)
%MEM 该进程的驻留内存1相对于物理总内存的比例
  • STAT 列所代表的意思
R running
S interruptable sleeping
D uninterruptable sleeping
T stopped
Z zombie
+ 前台进程
l 多线程进程
L 内存分页并带锁
N 低优先级进程
< 高优先级进程
s session leader,会话(子进程)发起者
  • 一些 ps 命令实例
ps axo pid,cmd,psr,ni,pri,rtprio             # BSD风格选项使用o选项后紧跟自定义的显示项目列表
常用组合:
    aux
    -ef
    -eFH
    -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,comm
    axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm

查询你拥有的所有进程
    ps -x
显示指定用户名(RUID)或用户ID的进程
    ps -fU apache
    ps -fU 48
显示指定用户名(EUID)或用户ID的进程
    ps -fu wang
    ps -fu 1000
查看以root用户权限(实际和有效ID)运行的每个进程
    ps -U root -u root
列出某个组拥有的所有进程(实际组ID:RGID或名称)
    ps -fG nginx
列出有效组名称(或会话)所拥有的所有进程
    ps -fg mysql
    ps -fg 27
显示指定的进程ID对应的进程
    ps -fp 1234
以父进程ID来显示其下所有的进程,如显示父进程为1234的所有进程
    ps -f --ppid 1234
显示指定PID的多个进程
    ps -fp 1204,1239,1263
要按tty显示所属进程
    ps -ft pts/0
以进程树显示系统中的进程如何相互链接
    ps -e --forest
以进程树显示指定的进程
    ps -f --forest -C sshd
    ps -ef --forest | grep -v grep | grep sshd
要显示一个进程的所有线程,将显示LWP(轻量级进程)以及NLWP(轻量级进程数)列
    ps -fL -C nginx
要列出所有格式说明符
    ps L
查看进程的PID,PPID,用户名和命令
    ps -eo pid,ppid,user,cmd
自定义格式显示文件系统组,ni值开始时间和进程的时间
    ps -p 1234 -o pid,ppid,fgroup,ni,lstart,etime
使用其PID查找进程名称:
    ps -p 1244 -o comm=
要以其名称选择特定进程,显示其所有子进程
    jps -C sshd,bash
查找指定进程名所有的所属PID,在编写需要从std输出或文件读取PID的脚本时这个参数很有用
    ps -C httpd,sshd -o pid=
检查一个进程的执行时间
    ps -eo comm,etime,user | grep nginx
查找占用最多内存和CPU的进程
    ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head
    ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head
显示安全信息
    ps -eM
    ps --context
使用以下命令以用户定义的格式显示安全信息
    ps -eo euser,ruser,suser,fuser,f,comm,label
使用watch实用程序执行重复的输出以实现对就程进行实时的监视,如下面的命令显示每秒钟的监视
    watch -n 1 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head'

3.nice 命令

  • 使用 nice 命令指定一个调度优先级来运行某程序
nice [OPTION] [COMMAND [ARG]...]
[root@centos8 ~]#nice -n 5 sleep 333&
[root@centos8 ~]#ps axo pri,cmd,pid,ni
...
 19 [kworker/1:3-xfs-cil/nvme0n  64292   0
 19 [kworker/u256:2-events_unbo  64294   0
 14 sleep 333                    64305   5
 19 ps axo pri,cmd,pid,ni        64306   0
...

[root@centos8 ~]#renice -n 7 64305
64305 (process ID) old priority 5, new priority 7
...
 19 [kworker/1:3-cgroup_destroy  64292   0
 19 [kworker/u256:2-events_unbo  64294   0
 12 sleep 333                    64305   7
 19 [kworker/3:1+events]         64310   0
 19 [kworker/2:1-cgroup_pidlist  64322   0
...

4.renice 命令

  • renice 命令可以更改一个正在运行的进程的优先级
renice [-n] priority pid...
  • 查看
ps axo pid,comm,ni
[root@centos8 ~]#renice -n 7 64305
64305 (process ID) old priority 5, new priority 7
...
 19 [kworker/1:3-cgroup_destroy  64292   0
 19 [kworker/u256:2-events_unbo  64294   0
 12 sleep 333                    64305   7
 19 [kworker/3:1+events]         64310   0
 19 [kworker/2:1-cgroup_pidlist  64322   0
...

5.pgrep 命令

  • pgrep 和 pkill 命令大部分选项相同,也就是大部分功能相同;但是 pgrep 一般用来基于进程名搜索某进程,
    pkill 一般基于进程名来发送相关信号给某进程。

  • 一般最灵活的搜索特定进程的方法为:ps 选项 | 其它命令

  • 而 pgrep 则可以按预定义的模式搜索进程

  • 用法

pgrep [options] pattern
-u uid: effective user,生效者
-U uid: real user,真正发起运行命令者
-t terminal: 与指定终端相关的进程
-l: 显示进程名
-a: 显示完整格式的进程名
-P pid: 显示指定进程的子进程
按确切的程序名称:/sbin/pidof
    pidof bash

6.kill 命令

  • kill 命令一般用来结束某进程,但是其还有其他功能,用于发送特定的信号给相关进程来控制某进程。
    以实现对进程管理,每个信号对应一个数字,信号名称以 SIG 开头(可省略),不区分大小写
显示当前系统可用信号:
    kill –l
    trap -l
常用信号:man 7 signal
1) SIGHUP   无须关闭进程而让其重读配置文件
2) SIGINT   中止正在运行的进程;相当于Ctrl+c
3) SIGQUIT  相当于ctrl+\
9) SIGKILL  强制杀死正在运行的进程
15) SIGTERM 终止正在运行的进程
18) SIGCONT 继续运行
19) SIGSTOP 后台休眠

指定信号的方法 :
   (1) 信号的数字标识:1, 2, 9
   (2) 信号完整名称:SIGHUP
   (3) 信号的简写名称:HUP

按PID来给某个进行发送信号:kill [-SIGNAL]  pid …
    kill –n SIGNAL pid
    kill –s SIGNAL pid
按名称:killall [-SIGNAL]  comm…
按模式:pkill [options] pattern
    -SIGNAL
    -u uid: effective user,生效者
    -U uid: real user,真正发起运行命令者
    -t terminal: 与指定终端相关的进程
    -l: 显示进程名(pgrep可用)
    -a: 显示完整格式的进程名(pgrep可用)
    -P pid: 显示指定进程的子进程
 Signal     Value     Action   Comment
       ──────────────────────────────────────────────────────────────────────
       SIGHUP        1       Term    Hangup detected on controlling terminal
                                     or death of controlling process
       SIGINT        2       Term    Interrupt from keyboard

       SIGQUIT       3       Core    Quit from keyboard
       SIGILL        4       Core    Illegal Instruction
       SIGABRT       6       Core    Abort signal from abort(3)
       SIGFPE        8       Core    Floating-point exception
       SIGKILL       9       Term    Kill signal
       SIGSEGV      11       Core    Invalid memory reference
       SIGPIPE      13       Term    Broken pipe: write to pipe with no
                                     readers; see pipe(7)
       SIGALRM      14       Term    Timer signal from alarm(2)
       SIGTERM      15       Term    Termination signal
       SIGUSR1   30,10,16    Term    User-defined signal 1
       SIGUSR2   31,12,17    Term    User-defined signal 2
       SIGCHLD   20,17,18    Ign     Child stopped or terminated
       SIGCONT   19,18,25    Cont    Continue if stopped
       SIGSTOP   17,19,23    Stop    Stop process
       SIGTSTP   18,20,24    Stop    Stop typed at terminal
       SIGTTIN   21,21,26    Stop    Terminal input for background process
       SIGTTOU   22,22,27    Stop    Terminal output for background process
  • pgrep 和 pkill 命令大部分选项相同,也就是大部分功能相同;但是 pgrep 一般用来基于进程名搜索某进程,
    pkill 一般基于进程名(支持正则表达式模式匹配)来发送相关信号给某进程。

  • killall 命令单纯的基于进程名来结束某进程

三.Linux 系统计划任务和用户计划任务

1.什么是作业?

  • 在 Linux 中的作业是指正在运行的还没有结束的命令或者任务。Linux 是个支持多任务的操作系统,
    其允许多个命令同时执行(多核 CPU 真正的同时执行;单核 CPU 并发执行)。每个正在进行的作业被唯
    一的作业号所标识。

  • 要查看和控制作业主要使用以下命令

    • jobs 列出正在运行或者挂起的作业
    • fg 将作业转换为前台作业
    • bg 将作业转换为后台作业
    • stop 挂起作业(Ctrl + z)
    • kill 结束作业(Ctrl + c)

2.Linux 的前后台作业管理

  • Linux 中某个命令或脚本默认运行时为前台进程,可以使用 Ctrl + c 结束其;如果发起该命令或者
    脚本的终端被关闭,那么该进程也就结束;这不利于需要长时间做某事的作业运行,在运行某命令或则
    脚本时可以在其后加上&符号来使其以后台作业的方式运行,这样即使使用 Ctrl+c 或者关闭终端也不会
    导致作业被终止。

  • 作业状态切换图示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bW11p2LR-1691714290369)(png/前后台作业切换.png)]

  • 例子:
[root@centos8 ~]#sleep 100 &
[1] 51898
[root@centos8 ~]#jobs
[1]+  Running                 sleep 100 &
  • 上面的"1"为作业号(作业被当前的 shell 所维护)。

  • "51898"是进程 ID 号即 PID(进程由系统维护)

  • 使用"kill %1"或者"kill 51898"结束该作业

  • 使用 bash 内置命令 disown 来移除活动的作业

  • 用法:disown PID

[root@centos8 ~]#sleep 2000 &
[1] 52837
[root@centos8 ~]#sleep 200 &
[2] 52838
[root@centos8 ~]#jobs
[1]-  Running                 sleep 2000 &
[2]+  Running                 sleep 200 &
[root@centos8 ~]#disown 52838                   # 指定作业PID来结束作业
[root@centos8 ~]#jobs
[1]+  Running                 sleep 2000 &
[root@centos8 ~]#disown sleep
[root@centos8 ~]#jobs
...
[root@centos8 ~]#sleep 200&
[1] 52855
[root@centos8 ~]#jobs
[1]+  Running                 sleep 200 &
[root@centos8 ~]#disown %1                     # 指定作业号来结束作业
[root@centos8 ~]#jobs
...
[root@centos8 ~]#sleep 200&
[1] 52868
[root@centos8 ~]#disown                        # 不指定任何信息,默认当前作业
[root@centos8 ~]#jobs
[root@centos8 ~]#

jobs

jobs -l    # 增加显示PID
jobs -n    # 当作业最后一次通知用户后状态有所改变时就显示相关信息
jobs -p    # 只显示作业进程号PID
jobs -r    # 只显示运行的作业
jobs -s    # 只显示停止的作业

fg

  • fg 恢复某个停止的后台作业或转换正在运行的后台作业为前台作业,并使之为当前作业。
[root@centos8 ~]#jobs
[1]-  Stopped                 sleep 2222
[2]   Running                 sleep 222546 &
[3]   Running                 sleep 222322 &
[4]+  Stopped                 sleep 2000
[5]   Running                 sleep 23424324 &
[root@centos8 ~]#fg %4
sleep 2000
^C
[root@centos8 ~]#

bg

  • bg 命令恢复某个挂起的后台作业为运行的后台作业
[root@centos8 ~]#jobs
[1]+  Stopped                 sleep 2222
[2]   Running                 sleep 222546 &
[3]   Running                 sleep 222322 &
[5]-  Running                 sleep 23424324 &
[root@centos8 ~]#bg %1
[1]+ sleep 2222 &
[root@centos8 ~]#jobs
[1]   Running                 sleep 2222 &
[2]   Running                 sleep 222546 &
[3]-  Running                 sleep 222322 &
[5]+  Running                 sleep 23424324 &
[root@centos8 ~]#

3.Linux 中同时运行多个进程的方法(多核 CPU)

  • 方法一:在命令或者脚本名后加&符号使其后台运行
[root@centos8 ~]#sleep 20&
[1] 43980
#!/bin/bash
p1.sh&
p2.sh&
p3.sh&
  • 方法二:使用圆括号来产生多个子进程,各子进程可以同时被运行
(job1&);(job2&);(job3&)
eg:
(p1.sh&);(p2sh&);(p3.sh&)
  • 方法三:使用花括号
{
    
    p1.sh& p2sh& p3.sh&}

4.Linux 任务计划

4.1 未来某时间点执行一次的任务

  • 使用 at 命令来定义未来某时间点执行一次的任务

  • at 命令所在包:at

  • at 命令用法:

at [option] TIME
常用选项:
    -V 显示版本信息
    -t time 时间格式  [[CC]YY]MMDDhhmm[.ss]
    -l 列出指定队列中等待运行的作业;相当于atq
    -d 删除指定的作业;相当于atrm
    -c 查看具体作业任务
    -f /path/file 指定的文件中读取任务
    -m 当任务被完成之后,将给用户发送邮件,即使没有标准输出
注意:作业执行命令的结果中的标准输出和错误以邮件通知给相关用户

TIME:定义出什么时候进行 at 这项任务的时间
    HH:MM [YYYY-mm-dd]
    noon, midnight, teatime(4pm)
    tomorrow
    now+#{minutes,hours,days, OR weeks}

HH:MM  02:00
    在今日的 HH:MM 进行,若该时刻已过,则明天此时执行任务
HH:MM YYYY-MM-DD   02:00 2016-09-20
    规定在某年某月的某一天的特殊时刻进行该项任务
HH:MM[am|pm] [Month] [Date]
    04pm March 17
    17:20 tomorrow
HH:MM[am|pm] + number [minutes|hours|days|weeks]
    在某个时间点再加几个时间后才进行该项任务
        now + 5 min
        02pm + 3 days
  • at 任务的执行方式
执行方式:
    1)交互式
    2)输入重定向
    3)at -f 文件
依赖于atd服务,需要启动才能实现at任务
at队列存放在/var/spool/at目录中
/etc/at.{
    
    allow,deny}文件控制用户是否能执行at任务,如果不存在则手工创建
    白名单:/etc/at.allow 默认不存在,只有该文件中的用户才能执行at命令
    黑名单:/etc/at.deny 默认存在,拒绝该文件中用户执行at命令,而没有在
at.deny 文件中的使用者则可执行
    如果两个文件都不存在,只有 root 可以执行 at 命令
  • 例子
[root@centos7 ~]#at 16:30
at> echo hahah
at> <EOT>                               # Ctrl+d 退出作业编辑
job 3 at Sat Oct 26 16:30:00 2019

[root@centos7 ~]#at -l                  # 列出作业队列
1       Sun Oct 27 16:15:00 2019 a root
2       Sun Oct 27 16:24:00 2019 a root
3       Sat Oct 26 16:30:00 2019 a root

[root@centos7 ~]#tree /var/spool/at
/var/spool/at
|-- a00001018fd26f
|-- a00002018fd278
|-- a00003018fccde                     # 当前计划作业
|-- spool

[root@centos7 ~]#cat /var/spool/at/a00003018fccde
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0
umask 22                                                                      XDG_SESSION_ID=75; export XDG_SESSION_ID                                      HOSTNAME=centos7.magedu.steve; export HOSTNAME                                SHELL=/bin/bash; export SHELL
...
...
${
    
    SHELL:-/bin/sh} <\< 'marcinDELIMITER4bbe8c69'
echo hahah                                                                                                                                                  marcinDELIMITER4bbe8c69

[root@centos7 ~]#mail                 # 作业完成后发邮件通知用户
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/root": 1 message 1 new
>N  1 root                  Sat Oct 26 16:30  14/494   "Output from your jo"
& 1
Message  1:
From [email protected]  Sat Oct 26 16:30:00 2019
Return-Path: <[email protected]>
X-Original-To: root                                                           Delivered-To: [email protected]
Subject: Output from your job        3
To: [email protected]
Date: Sat, 26 Oct 2019 16:30:00 +0800 (CST)
From: [email protected] (root)
Status: R

hahah                                # 作业的标准输出内容

&

4.2 未来周期性执行的任务

4.2.1 实现 cron 计划任务的前提

  • 安装相关程序包
cronie
    主程序包,提供crond守护进程及相关辅助工具
crontabs
    包含CentOS提供系统维护任务
cronie-anacron
    cronie的补充程序,用于监控cronie任务执行状况,如cronie中的任务在过去应该运行的时间
    点未能正常运行,则anacron会随后启动一次此任务
  • 确保 crond 守护处于运行状态
CentOS 7:
    systemctl status crond
CentOS 6:
    service crond status
  • 计划周期性执行的任务提交给 crond,到指定时间会自动运行

  • 系统 cron 任务:系统维护的周期性作业,位于: /etc/crontab 文件内,一般只有 root 可以更改。

  • 用户 cron 任务:使用 crontab 命令来创建用户各自的周期性任务

  • 日志:/var/log/cron

  • 使用 crontab 命令来定义周期性计划任务

4.2.2 系统 cron 计划任务

  • 系统 cron 任务:/etc/crontab
  • 注释行以 # 开头
  • 详情参见 man 4 rontab
[root@centos7 ~]#cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
  • 例如:晚上 9 点 10 分以用户 steve 的身份运行 echo 命令

10 21 * * * steve /bin/echo “Hello there!!”

  • 时间表示的方法
时间表示法:
(1) 特定值
    给定时间点有效取值范围内的值
(2) *
    给定时间点上有效取值范围内的所有值
    表示“每...”
(3) 离散取值
    #,#,#
(4) 连续取值
    #-#
(5) 在指定时间范围上,定义步长
    /#: #即为步长
  • 可以替换的时间格式
@yearly   0 0 1 1 *
@annually 0 0 1 1 *
@monthly  0 0 1 * *
@weekly   0 0 * * 0
@daily    0 0 * * *
@hourly   0 * * * *
@reboot   Run once after reboot
示例:每3小时echo和wall命令
0 */3 * * * wang /bin/echo “howdy”;  wall “welcome to Magedu!
  • 例子:每 3 小时 echo 和 wall 命令

0 _/3 _ * * steve /bin/echo “Done something!”; wall “Done something again!”

  • 系统计划任务所涉及的配置文件及任务队列
配置文件 /etc/crontab
配置文件 /etc/cron.d/
脚本 /etc/cron.hourly/
脚本 /etc/cron.daily/
脚本 /etc/cron.weekly/
脚本 /etc/cron.monthly/

4.2.3anacron 系统

运行计算机关机时cron不运行的任务,CentOS6以后版本取消anacron服务,由crond服务管理
对笔记本电脑、台式机、工作站、偶尔要关机的服务器及其它不一直开机的系统很重要对很有用
配置文件:/etc/anacrontab,负责执行/etc/ cron.daily /etc/cron.weekly
/etc/cron.monthly中系统任务
    •字段1:如果在这些日子里没有运行这些任务……
    •字段2:在重新引导后等待这么多分钟后运行它
    •字段3:任务识别器,在日志文件中标识
    •字段4:要执行的任务
由/etc/cron.hourly/0anacron执行
当执行任务时,更新/var/spool/anacron/cron.daily 文件的时间戳

4.2.4 管理临时文件

CentOS7使用systemd-tmpfiles-setup服务实现
CentOS6使用/etc/cron.daily/tmpwatch定时清除临时文件
配置文件:
    /etc/tmpfiles.d/*.conf
    /run/tmpfiles.d/*.conf
    /usr/lib/tmpfiles/*.conf
/usr/lib/tmpfiles.d/tmp.conf
    d /tmp 1777 root root 10d
    d /var/tmp 1777 root root 30d
命令:
    systemd-tmpfiles –clean|remove|create  configfile

4.2.5 用户计划任务

  • crontab 命令定义
  • 每个用户都有专用的 cron 任务文件:/var/spool/cron/USERNAME
  • crontab 命令:
crontab [-u user] [-l | -r | -e] [-i]
-l 列出所有任务
-e 编辑任务
-r 移除所有任务
-i 同-r一同使用,以交互式模式移除指定任务
-u user 仅root可运行,指定用户管理cron任务
  • 控制用户执行计划任务:/etc/cron.{allow,deny}

4.2.6 at 和 crontab 对比

  • 一次性作业使用 at
  • 重复性作业使用 crontab
Create at TIME crontab -e
List at -l crontab -l
Details at -c jobnum crontab -l
Remove at -d jobnum crontab -r
Edit N/A crontab -e
  • 没有被重定向的输出会被邮寄给用户
  • root 能够修改其它用户的作业
  • 注意:运行结果的标准输出和错误都以邮件通知给相关用户
(1) COMMAND > /dev/null
(2) COMMAND &> /dev/null
  • 对于 cron 任务来讲,%有特殊用途;如果在命令中要使用%,则需要转义,将%
    放置于单引号中,则可不用转义

思考

  • (1) 如何在秒级别运行任务?
* * * * * for min in 0 1 2; do echo "hi"; sleep 20; done
  • (2) 如何实现每 7 分钟运行一次任务?
*/6 * * * * for min in 0 1 2; do sleep 1m; echo "hi"; done
sleep命令:
    sleep NUMBER[SUFFIX]...
SUFFIX:
    s: 秒, 默认
    m: 分
    h: 小时
    d: 天

5.练习

1、每周的工作日 1:30,将/etc 备份至/backup 目录中,保存的文件名称格式为"etcbak-yyyy-mm-dd-HH.tar.xz",其中日期是前一天的时间

vim backup.sh
#!/bin/bash
tar Jcf /backup/etcbak-`date -d "-1 day" +%F-%H`.tar.xz /etc/ &
...
chmod +x backup.sh
crontab -e
30 1 * * 1-5 /root/backup.sh

2、每两小时取出当前系统/proc/meminfo 文件中以 S 或 M 开头的信息追加至/tmp/meminfo.txt 文件中

vim meminfo.sh
#!/bin/bash
INFO=`grep -E '^(S|M).*' /proc/meminfo`
touch /tmp/meminfo.txt
cat "$INFO" >> /tmp/meminfo.txt &> /dev/null
...
chmod +x meminfo.sh
crontab -e
0 */2 * * * /root/meminfo.sh

3、工作日时间,每 10 分钟执行一次磁盘空间检查,一旦发现任何分区利用率高于 80%,就执行 wall 警报

vim check.sh
#!/bin/bash
THRESHOLD=80
D_MAX_USAGE=`df  | sed -nr '/^\/dev\/sd.*/s#.* (.+)% .*#\1#p' | sort -nr | he ad -n1`
I_MAX_USAGE=`df -i  | sed -nr '/^\/dev\/sd.*/s#.* (.+)% .*#\1#p' | sort -nr | he ad -n1`
if [[ "$THRESHOLD"  -eq "$D_MAX_USAGE"]]; do
    wall "Disk usage almost full!!"
elif [[ "$THRESHOLD"  -eq "$I_MAX_USAGE"]]; do
    wall "Inode usage almost full!!"
done
...
chmod +x check.sh
crontab -e
*/10 * * * 1-5 /root/check.sh

注脚


  1. 驻留内存:即 RSS(resident set size)是驻留集合大小,即进程所使用的非交换区的物理内存。 ↩︎

おすすめ

転載: blog.csdn.net/wang11876/article/details/132223359