「リアルタイムプロセス管理」の版間の差分
(同期) |
|||
(2人の利用者による、間の4版が非表示) | |||
1行目: | 1行目: | ||
[[Category:セキュリティ]] |
[[Category:セキュリティ]] |
||
[[en:Realtime process management]] |
[[en:Realtime process management]] |
||
+ | {{Related articles start}} |
||
+ | {{Related|cgroups}} |
||
+ | {{Related|リアルタイムカーネル}} |
||
+ | {{Related|パフォーマンスの最大化}} |
||
+ | {{Related articles end}} |
||
この記事では起動時だけではなく、リアルタイムにプロセススレッドの優先度を変更する情報を記載しています。個別のプロセスあるいは特定のグループによって実行された全てのプロセスの CPU やメモリなどのリソースの使用量を制御する方法を説明します。 |
この記事では起動時だけではなく、リアルタイムにプロセススレッドの優先度を変更する情報を記載しています。個別のプロセスあるいは特定のグループによって実行された全てのプロセスの CPU やメモリなどのリソースの使用量を制御する方法を説明します。 |
||
21行目: | 26行目: | ||
{{ic|/etc/security/limits.conf}} ファイルにはシステムリソースの制限を設定する PAM モジュール {{ic|pam_limits}} の設定が書き込まれています。このファイルを編集することで全てのプロセスや個別のグループのデフォルトの nice レベルを定義したり、メモリアドレス領域の制限をかけたりすることができます。 |
{{ic|/etc/security/limits.conf}} ファイルにはシステムリソースの制限を設定する PAM モジュール {{ic|pam_limits}} の設定が書き込まれています。このファイルを編集することで全てのプロセスや個別のグループのデフォルトの nice レベルを定義したり、メモリアドレス領域の制限をかけたりすることができます。 |
||
− | {{Note|Systemd サービスによって初期化されたプロセスは |
+ | {{Note|Systemd サービスによって初期化されたプロセスは [[limits.conf]] を無視します。{{ic|.service}} ファイルで設定する必要があります。詳しくは {{man|5|systemd.exec}} を見てください。}} |
{{ic|pam_limits}} によるリソースの制限には2つのタイプがあります: '''ハードリミット'''と'''ソフトリミット'''です。ハードリミットは {{ic|root}} によって設定されカーネルによって執行されますが、ソフトリミットについてはハードリミットが許可する範囲内でユーザーが設定できます。デフォルトでは、Arch は {{ic|-}} リミットを使っており、ハードリミットとソフトリミットの両方が参照されます。 |
{{ic|pam_limits}} によるリソースの制限には2つのタイプがあります: '''ハードリミット'''と'''ソフトリミット'''です。ハードリミットは {{ic|root}} によって設定されカーネルによって執行されますが、ソフトリミットについてはハードリミットが許可する範囲内でユーザーが設定できます。デフォルトでは、Arch は {{ic|-}} リミットを使っており、ハードリミットとソフトリミットの両方が参照されます。 |
||
+ | Arch Linux のデフォルト設定では非特権プロセスで許可されている最大リアルタイム優先度は 0 で、上げることができる nice 値は最大で 0 までとなっています。{{ic|audio}} グループに対してはカスタム設定が存在します。{{ic|memlock}} アイテムはロックできるメモリアドレス領域の最大値を 40,000 KiB に設定します。以下のように確認できます: |
||
− | The default Arch Linux settings set the maximum real-time priority allowed for non-priveleged processes to 0, the maximum nice priority allowed to raise to 0, and some custom settings for the {{ic|audio}} group. Finally, the {{ic|memlock}} item sets the maximum locked-in memory address space to 40,000 KiB. These defaults are shown below: |
||
{{bc|<nowiki> |
{{bc|<nowiki> |
||
35行目: | 40行目: | ||
</nowiki>}} |
</nowiki>}} |
||
+ | ハイパフォーマンスなオーディオを使いたい場合などに上記の設定を変更します。{{ic|jack-server}} を {{ic|hydrogen}} や {{ic|ardour}} で使うだけならデフォルト設定で問題ありません。さらに高いパフォーマンスを必要とするオーディオアプリケーションでは {{ic|rt_prio}} を 65 から 80 以上の値に再定義すると良いでしょう。以下の設定で {{ic|ardour}} の動作が良くなります: |
||
− | An example for why one might want to alter these settings is to get high-performance audio working. The defaults are permissive enough to get {{ic|jack-server}} running with {{ic|hydrogen}} or {{ic|ardour}}. However, for higher performance audio applications it might be necessary to redefine the values for {{ic|rt_prio}} from 65 to 80 or even higher! The following settings work well with {{ic|ardour}}: |
||
{{bc| |
{{bc| |
||
44行目: | 49行目: | ||
詳しくは[[プロオーディオ]]を見てください。 |
詳しくは[[プロオーディオ]]を見てください。 |
||
− | PAM limits で設定できる値は星の数ほどあります。ここで説明しているのはあくまで概要だけなので、より深く理解するために {{ |
+ | PAM limits で設定できる値は星の数ほどあります。ここで説明しているのはあくまで概要だけなので、より深く理解するために {{man|5|limits.conf}} のページを読むことを強く推奨します。 |
== ハードリアルタイムとソフトリアルタイム == |
== ハードリアルタイムとソフトリアルタイム == |
||
+ | リアルタイムとは他のプロセスによって割り込みが発生しないで時間内に実行することができるプロセスのことです。ただし、サイクルはときどき破棄される可能性があります。電源供給が少なかったり高い優先度のプロセスがある場合などに発生します。問題を解決するためにリアルタイム品質のスケーリングが存在します。この記事ではソフトリアルタイムを取り扱っています。ハードリアルタイムは基本的にそこまで必要とされる場合は多くありません。例えば自動車の ABS (アンチロックブレーキシステム) などです。ブレーキが効かなかった場合に二度目はありません。 |
||
− | Realtime is a synonym for a process which has the capability to run |
||
− | in time without being interrupted by any other process. However, cycles can occasionally be dropped despite this. Low power supply or a process with higher priority could be a potential cause. To solve this problem, there is a scaling of realtime quality. This article deals with '''soft''' realtime. Hard realtime is usually not so much desired as it is ''needed''. An example could be made for car's ABS (anti-lock braking system). This can not be "rendered" and there is no second chance. |
||
== Power is nothing without control == |
== Power is nothing without control == |
||
+ | realtime-lsm モジュールは特定の UID に属するユーザーにさらに強いケイパビリティを手に入れる権限を与えます。rlimit も同じように機能しますが、細かい制御が可能です。ユーザーごと、あるいはグループレベルでケイパビリティを制御することができる新しい機能が PAM には存在します。現在のバージョン (0.80-2) では最初は正しく設定されておらず問題が発生します。PAM を使うことで特定のユーザーや特定のユーザーグループにリアルタイムの優先度を与えることができます。PAM のコンセプトではアプリケーションごとに権限を与えることすら可能となる予定ですが、今のところは不可能となっています。 |
||
− | The realtime-lsm module granted the right to get higher capabilities to users belonging to a certain UID. The rlimit way works similar, but it can be controlled graduated finer. There is a new functionality in PAM which can be used to control the capabilities on a per user or a per group level. In the current version (0.80-2) these values are not set correctly out of the box and still create problems. |
||
− | With PAM you can grant realtime priority to a certain user or to a certain user group. PAM's concept makes it imaginable that there will be ways in the future to grant rights on a per application level; however, this is not yet possible. |
||
+ | == ヒントとテクニック == |
||
− | == Tips and tricks == |
||
=== PAM が有効なログイン === |
=== PAM が有効なログイン === |
||
76行目: | 79行目: | ||
}} |
}} |
||
+ | {{ic|login}} や PolicyKit などは全て {{ic|pam_limits.so}} モジュールを必要とします。これは良いことであり PAM の制限が適用されることを意味します。 |
||
− | So we see that {{ic|login}}, PolicyKit, and the others all require the pam_limits.so module. This is a good thing, and means PAM limits will be enforced. |
||
=== コンソール/自動ログイン === |
=== コンソール/自動ログイン === |
||
93行目: | 96行目: | ||
=== RLIMIT 定義 === |
=== RLIMIT 定義 === |
||
+ | ; RLIMIT_AS: プロセスの仮想メモリ (アドレス領域) の最大容量をバイト単位で設定します。brk(2), mmap(2), mremap(2) のコールに影響し、制限を越えると ENOMEM エラーが発生します。また、自動的なスタック拡張も失敗します (SIGSEGV が生成され sigaltstack(2) による別のスタックが利用可能でなければプロセスが kill されます)。RLIMIT_AS の値は long であるため、long が32ビットのマシンでは、制限は最大で 2 GiB であるか、あるいは無制限になります。 |
||
− | ; RLIMIT_AS: The maximum size of the process’s virtual memory (address space) in bytes. This limit affects calls to brk(2), mmap(2) and mremap(2), which fail with the error ENOMEM upon exceeding this limit. Also automatic stack expansion will fail (and generate a SIGSEGV that kills the process if no alternate stack has been made available via sigaltstack(2)). Since the value is a long, on machines with a 32-bit long either this limit is at most 2 GiB, or this resource is unlimited. |
||
+ | ; RLIMIT_CORE: コアファイルの最大容量。0 の場合はコアダンプファイルが作成されません。0 以外の場合、巨大なダンプは指定された容量まで切り詰められます。 |
||
− | ; RLIMIT_CORE: Maximum size of core file. When 0 no core dump files are created. When non-zero, larger dumps are truncated to this size. |
||
+ | ; RLIMIT_CPU: CPU 時間の制限 (秒単位)。プロセスがソフトリミットに達すると、SIGXCPU シグナルが送信されます。このシグナルが送られるとデフォルトではプロセスが終了します。ただし、シグナルをハンドラがキャッチしてメインプログラムに制御を返すこともあります。プロセスが CPU 時間を消費し続ける場合、ハードリミットに達するまで1秒ごとに SIGXCPU が送信され、ハードリミットに達すると SIGKILL が送信されます (Linux 2.2 から 2.6 までの挙動です。ソフトリミットに達しても CPU 時間を浪費し続けるプロセスをどのように扱うかは実装によって変わります。シグナルをキャッチする必要があるポータブルアプリケーションは大抵の場合 SIGXCPU を最初に受け取ったときに終了します)。 |
||
− | ; RLIMIT_CPU: CPU time limit in seconds. When the process reaches the soft limit, it is sent a SIGXCPU signal. The default action for this signal is to terminate the process. However, the signal can be caught, and the handler can return control to the main program. If the process continues to consume CPU time, it will be sent SIGXCPU once per second until the hard limit is reached, at which time it is sent SIGKILL. (This latter point describes Linux 2.2 through 2.6 behavior. Implementations vary in how they treat processes which continue to consume CPU time after reaching the soft limit. Portable applications that need to catch this signal should perform an orderly termination upon first receipt of SIGXCPU.) |
||
+ | ; RLIMIT_DATA: プロセスのデータセグメント (初期化されたデータ・初期化されていないデータ・ヒープ) の最大容量。この制限は brk(2) と sbrk(2) のコールに影響し、リソースのソフトリミットに達すると ENOMEM エラーでコールが失敗します。 |
||
− | ; RLIMIT_DATA: The maximum size of the process’s data segment (initialized data, uninitialized data, and heap). This limit affects calls to brk(2) and sbrk(2), which fail with the error ENOMEM upon encountering the soft limit of this resource. |
||
+ | ; RLIMIT_FSIZE: プロセスが作成できるファイルの最大容量。この制限を超えてファイルを書き込むと SIGXFSZ シグナルが送信されます。デフォルトではシグナルによってプロセスが終了しますが、プロセスがシグナルをキャッチする場合もあり、その場合は関連するシステムコール (例: write(2), truncate(2)) が EFBIG エラーで失敗します。 |
||
− | ; RLIMIT_FSIZE: The maximum size of files that the process may create. Attempts to extend a file beyond this limit result in delivery of a SIGXFSZ signal. By default, this signal terminates a process, but a process can catch this signal instead, in which case the relevant system call (e.g., write(2), truncate(2)) fails with the error EFBIG. |
||
− | ; RLIMIT_LOCKS: ( |
+ | ; RLIMIT_LOCKS: (初期の Linux 2.4 のみ) プロセスが作成できる flock(2) のロックと fcntl(2) のリースの合計数を制限します。 |
; RLIMIT_MEMLOCK: The maximum number of bytes of memory that may be locked into RAM. In effect this limit is rounded down to the nearest multiple of the system page size. This limit affects mlock(2) and mlockall(2) and the mmap(2) MAP_LOCKED operation. Since Linux 2.6.9 it also affects the shmctl(2) SHM_LOCK operation, where it sets a maximum on the total bytes in shared memory segments (see shmget(2)) that may be locked by the real user ID of the calling process. The shmctl(2) SHM_LOCK locks are accounted for separately from the per-process memory locks established by mlock(2), mlockall(2), and mmap(2) MAP_LOCKED; a process can lock bytes up to this limit in each of these two categories. In Linux kernels before 2.6.9, this limit controlled the amount of memory that could be locked by a privileged process. Since Linux 2.6.9, no limits are placed on the amount of memory that a privileged process may lock, and this limit instead governs the amount of memory that an unprivileged process may lock. |
; RLIMIT_MEMLOCK: The maximum number of bytes of memory that may be locked into RAM. In effect this limit is rounded down to the nearest multiple of the system page size. This limit affects mlock(2) and mlockall(2) and the mmap(2) MAP_LOCKED operation. Since Linux 2.6.9 it also affects the shmctl(2) SHM_LOCK operation, where it sets a maximum on the total bytes in shared memory segments (see shmget(2)) that may be locked by the real user ID of the calling process. The shmctl(2) SHM_LOCK locks are accounted for separately from the per-process memory locks established by mlock(2), mlockall(2), and mmap(2) MAP_LOCKED; a process can lock bytes up to this limit in each of these two categories. In Linux kernels before 2.6.9, this limit controlled the amount of memory that could be locked by a privileged process. Since Linux 2.6.9, no limits are placed on the amount of memory that a privileged process may lock, and this limit instead governs the amount of memory that an unprivileged process may lock. |
||
− | ; RLIMIT_MSGQUEUE: ( |
+ | ; RLIMIT_MSGQUEUE: (Linux 2.6.8 以上) Specifies the limit on the number of bytes that can be allocated for POSIX message queues for the real user ID of the calling process. This limit is enforced for mq_open(3). Each message queue that the user creates counts (until it is removed) against this limit according to the formula: bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) + attr.mq_maxmsg * attr.mq_msgsize where attr is the mq_attr structure specified as the fourth argument to mq_open(3). The first addend in the formula, which includes sizeof(struct msg_msg *) (4 bytes on Linux/i386), ensures that the user cannot create an unlimited number of zero-length messages (such messages nevertheless each consume some system memory for bookkeeping overhead). |
; RLIMIT_NICE: (since Linux 2.6.12, but see BUGS below) Specifies a ceiling to which the process’s nice value can be raised using setpriority(2) or nice(2). The actual ceiling for the nice value is calculated as 20 – rlim_cur. (This strangeness occurs because negative numbers cannot be specified as resource limit values, since they typically have special meanings. For example, RLIM_INFINITY typically is the same as -1.) |
; RLIMIT_NICE: (since Linux 2.6.12, but see BUGS below) Specifies a ceiling to which the process’s nice value can be raised using setpriority(2) or nice(2). The actual ceiling for the nice value is calculated as 20 – rlim_cur. (This strangeness occurs because negative numbers cannot be specified as resource limit values, since they typically have special meanings. For example, RLIM_INFINITY typically is the same as -1.) |
||
; RLIMIT_NOFILE: Specifies a value one greater than the maximum file descriptor number that can be opened by this process. Attempts (open(2), pipe(2), dup(2), etc.) to exceed this limit yield the error EMFILE. (Historically, this limit was named RLIMIT_OFILE on BSD.) |
; RLIMIT_NOFILE: Specifies a value one greater than the maximum file descriptor number that can be opened by this process. Attempts (open(2), pipe(2), dup(2), etc.) to exceed this limit yield the error EMFILE. (Historically, this limit was named RLIMIT_OFILE on BSD.) |
||
107行目: | 110行目: | ||
; RLIMIT_RTPRIO: (Since Linux 2.6.12, but see BUGS) Specifies a ceiling on the real-time priority that may be set for this process using sched_setscheduler(2) and sched_setparam(2). |
; RLIMIT_RTPRIO: (Since Linux 2.6.12, but see BUGS) Specifies a ceiling on the real-time priority that may be set for this process using sched_setscheduler(2) and sched_setparam(2). |
||
; RLIMIT_RTTIME: (Since Linux 2.6.25) Specifies a limit on the amount of CPU time that a process scheduled under a real-time scheduling policy may consume without making a blocking system call. For the purpose of this limit, each time a process makes a blocking system call, the count of its consumed CPU time is reset to zero. The CPU time count is not reset if the process continues trying to use the CPU but is preempted, its time slice expires, or it calls sched_yield(2). Upon reaching the soft limit, the process is sent a SIGXCPU signal. If the process catches or ignores this signal and continues consuming CPU time, then SIGXCPU will be generated once each second until the hard limit is reached, at which point the process is sent a SIGKILL signal. The intended use of this limit is to stop a runaway real-time process from locking up the system. |
; RLIMIT_RTTIME: (Since Linux 2.6.25) Specifies a limit on the amount of CPU time that a process scheduled under a real-time scheduling policy may consume without making a blocking system call. For the purpose of this limit, each time a process makes a blocking system call, the count of its consumed CPU time is reset to zero. The CPU time count is not reset if the process continues trying to use the CPU but is preempted, its time slice expires, or it calls sched_yield(2). Upon reaching the soft limit, the process is sent a SIGXCPU signal. If the process catches or ignores this signal and continues consuming CPU time, then SIGXCPU will be generated once each second until the hard limit is reached, at which point the process is sent a SIGKILL signal. The intended use of this limit is to stop a runaway real-time process from locking up the system. |
||
+ | ; RLIMIT_SIGPENDING: (Linux 2.6.8 以上) プロセスを呼び出している実ユーザー ID に対してキューに入れられるシグナルの数の制限を指定します。標準シグナルとリアルタイムシグナルの両方が制限をチェックするときにカウントされます。ただし制限が適用されるのは sigqueue(2) だけです。kill(2) を使用することで常にまだキューに入れられていないシグナルのインスタンスをキューに入れることができます。 |
||
− | ; RLIMIT_SIGPENDING: (Since Linux 2.6.8) Specifies the limit on the number of signals that may be queued for the real user ID of the calling process. Both standard and real-time signals are counted for the purpose of checking this limit. However, the limit is only enforced for sigqueue(2); it is always possible to use kill(2) to queue one instance of any of the signals that are not already queued to the process. |
||
+ | ; RLIMIT_STACK: プロセススタックの最大容量 (バイト単位)。上限に達すると、SIGSEGV シグナルが生成されます。このシグナルを処理するには、プロセスは別のシグナルスタック (sigaltstack(2)) を使用しなければなりません。 |
||
− | ; RLIMIT_STACK: The maximum size of the process stack, in bytes. Upon reaching this limit, a SIGSEGV signal is generated. To handle this signal, a process must employ an alternate signal stack (sigaltstack(2)). |
||
=== スケジューリングポリシー === |
=== スケジューリングポリシー === |
||
114行目: | 117行目: | ||
CFS は3つのスケジューリングポリシーを実装しています: |
CFS は3つのスケジューリングポリシーを実装しています: |
||
; SCHED_NORMAL (別名 SCHED_OTHER): 通常のタスクに使われるスケジューリングポリシー。 |
; SCHED_NORMAL (別名 SCHED_OTHER): 通常のタスクに使われるスケジューリングポリシー。 |
||
+ | ; SCHED_BATCH: 通常のタスクと比べて優先度が低くなり、反応が鈍くなるかわりにタスクを長く動作させてキャッシュをより活用することができます。バッチジョブに適しています。 |
||
− | ; SCHED_BATCH: Does not preempt nearly as often as regular tasks would, thereby allowing tasks to run longer and make better use of caches but at the cost of interactivity. This is well suited for batch jobs. |
||
+ | ; SCHED_IDLE: nice 19 よりも優先度が低くなります。ただしマシンをデッドロックさせるような優先順位の逆転を防ぐために、完全なアイドルタイマースケジューラではありません。 |
||
− | ; SCHED_IDLE: This is even weaker than nice 19, but its not a true idle timer scheduler in order to avoid to get into priority inversion problems which would deadlock the machine. |
||
=== スケジューリングクラス === |
=== スケジューリングクラス === |
||
− | ; IOPRIO_CLASS_RT: リアルタイム io クラスです。RT スケジューリングクラスは、システムで何が動作しているのかに関わらず、ディスクに対する第一級のアクセス権限を与えられます。そのため RT クラスは注意して使用しないと、他のプロセスに多大な影響を与える可能性があります。ベストエフォートクラスと同じように、スケジューリングウィンドウでどれだけタイムスライスをプロセスに与えるか定義する8つのプライオリティレベルが存在します。RT スケジューリングクラスはシステム内の他のどんなクラスよりも高い優先度を持っているため、RT スケジューリングクラスのプロセスはいかなる時でも真っ先にディスクにアクセスすることができます。 |
+ | ; IOPRIO_CLASS_RT: リアルタイム io クラスです。RT スケジューリングクラスは、システムで何が動作しているのかに関わらず、ディスクに対する第一級のアクセス権限を与えられます。そのため RT クラスは注意して使用しないと、他のプロセスに多大な影響を与える可能性があります。ベストエフォートクラスと同じように、スケジューリングウィンドウでどれだけタイムスライスをプロセスに与えるか定義する8つのプライオリティレベルが存在します。RT スケジューリングクラスはシステム内の他のどんなクラスよりも高い優先度を持っているため、RT スケジューリングクラスのプロセスはいかなる時でも真っ先にディスクにアクセスすることができます。将来的には必要なデータレートを指定することで直接適切なパフォーマンスが出せるようになる可能性があります。 |
+ | ; IOPRIO_CLASS_BE: ベストエフォートのスケジューリングクラスで、特に優先度が設定されていないプロセスのデフォルトになります。プログラムは io の優先度について CPU の nice 設定を継承します。このクラスは 0-7 の優先度を指定でき、低い値ほど優先されます。同じベストエフォート優先度のプログラムはラウンドロビン方式で回されます。クラスデータはプロセスが使用できる io 帯域幅を決定し、大雑把に実装されている cpu の nice レベルに直接マッピングされます。0 が最高の BE レベルで、7 が最低です。cpu の nice 値と io の nice 値は次のようにしてマッピングされます: io_nice = (cpu_nice + 20) / 5。 |
||
− | ; IOPRIO_CLASS_BE: This is the best-effort scheduling class, which is the default for any process that hasn’t set a specific io priority. This is the default scheduling class for any process that hasn’t asked for a specific io priority. Programs inherit the CPU nice setting for io priorities. This class takes a priority argument from 0-7, with lower number being higher priority. Programs running at the same best effort priority are served in a round-robin fashion. The class data determines how much io bandwidth the process will get, it’s directly mappable to the cpu nice levels just more coarsely implemented. 0 is the highest BE prio level, 7 is the lowest. The mapping between cpu nice level and io nice level is determined as: io_nice = (cpu_nice + 20) / 5. |
||
+ | ; IOPRIO_CLASS_IDLE: アイドルスケジューリングクラスです。このレベルで動作しているプロセスは他のプロセスがディスクを必要としないときだけ io を使用する時間を得ます。アイドル io プロセスは通常のシステムの活動には全く影響を与えません。このスケジューリングクラスは優先度を引数で指定できません。アイドルクラスにクラスデータは存在しません。 |
||
− | ; IOPRIO_CLASS_IDLE: This is the idle scheduling class, processes running at this level only get io time when no one else needs the disk. A program running with idle io priority will only get disk time when no other program has asked for disk io for a defined grace period. The impact of idle io processes on normal system activity should be zero. This scheduling class does not take a priority argument. The idle class has no class data, since it doesn’t really apply here. |
||
== 参照 == |
== 参照 == |
||
* [http://cuddletech.com/?p=330 IO Benchmarking: How, why and with what] |
* [http://cuddletech.com/?p=330 IO Benchmarking: How, why and with what] |
||
− | * [http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt CGROUPS カーネルドキュメント] |
||
− | * [http://www.askapache.com/linux-unix/optimize-nice-ionice.html Optimizing servers and processes for speed with ionice, nice, ulimit] |
||
* [http://sebastien.godard.pagesperso-orange.fr/ SYSSTAT ユーティリティホームページ] |
* [http://sebastien.godard.pagesperso-orange.fr/ SYSSTAT ユーティリティホームページ] |
||
* [http://gaarai.com/2009/03/06/multitasking-from-the-linux-command-line-plus-process-prioritization/ Multitasking from the Linux command line and process prioritization] |
* [http://gaarai.com/2009/03/06/multitasking-from-the-linux-command-line-plus-process-prioritization/ Multitasking from the Linux command line and process prioritization] |
2017年12月30日 (土) 01:14時点における最新版
関連記事
この記事では起動時だけではなく、リアルタイムにプロセススレッドの優先度を変更する情報を記載しています。個別のプロセスあるいは特定のグループによって実行された全てのプロセスの CPU やメモリなどのリソースの使用量を制御する方法を説明します。
新しいプロセッサの多くは大量の動画や音声を同時に再生できるほどの能力を持っていますが、それでもスレッドがプロセッサを占有して他の処理に遅延が発生する可能性が全く無いわけではありません。そのような場合、音声や動画にずれが生じてしまう恐れがあり、単に趣味で音楽を聞いているだけなら煩わしいだけですみますが、作曲したり動画を編集して生業を立てている人にとっては非常に深刻な問題です。
一番簡単な解決方法は音声や動画のプロセスに高い優先度を割り当てることです。しかしながら、通常ユーザーは比較的高い nice 値 (つまり優先度は低い) しか設定できず、0未満の低い nice 値を設定してプロセスを起動できるのは root だけとなっています。これによって通常ユーザーはシステムの重要な役割を担っているプロセスの優先度を下げられないようになっています。この制限は特にユーザーが複数存在するマシンで重要です。
目次
設定
デフォルトで、Arch ではリアルタイムの優先度変更が有効になっており、ユーザーから簡単に設定を編集することができます。例えば、0以下の nice 値をユーザーが設定できるようにするには、PAM によって設定されているデフォルトのハードリミットを調整する必要があります。
pam
公式リポジトリの pam パッケージには Linux カーネルの pluggable authentication modules が入っています。
PAM の設定
/etc/security/limits.conf
ファイルにはシステムリソースの制限を設定する PAM モジュール pam_limits
の設定が書き込まれています。このファイルを編集することで全てのプロセスや個別のグループのデフォルトの nice レベルを定義したり、メモリアドレス領域の制限をかけたりすることができます。
pam_limits
によるリソースの制限には2つのタイプがあります: ハードリミットとソフトリミットです。ハードリミットは root
によって設定されカーネルによって執行されますが、ソフトリミットについてはハードリミットが許可する範囲内でユーザーが設定できます。デフォルトでは、Arch は -
リミットを使っており、ハードリミットとソフトリミットの両方が参照されます。
Arch Linux のデフォルト設定では非特権プロセスで許可されている最大リアルタイム優先度は 0 で、上げることができる nice 値は最大で 0 までとなっています。audio
グループに対してはカスタム設定が存在します。memlock
アイテムはロックできるメモリアドレス領域の最大値を 40,000 KiB に設定します。以下のように確認できます:
* - rtprio 0 * - nice 0 @audio - rtprio 65 @audio - nice -10 @audio - memlock 40000
ハイパフォーマンスなオーディオを使いたい場合などに上記の設定を変更します。jack-server
を hydrogen
や ardour
で使うだけならデフォルト設定で問題ありません。さらに高いパフォーマンスを必要とするオーディオアプリケーションでは rt_prio
を 65 から 80 以上の値に再定義すると良いでしょう。以下の設定で ardour
の動作が良くなります:
@audio - rtprio 70 @audio - memlock 250000
詳しくはプロオーディオを見てください。
PAM limits で設定できる値は星の数ほどあります。ここで説明しているのはあくまで概要だけなので、より深く理解するために limits.conf(5) のページを読むことを強く推奨します。
ハードリアルタイムとソフトリアルタイム
リアルタイムとは他のプロセスによって割り込みが発生しないで時間内に実行することができるプロセスのことです。ただし、サイクルはときどき破棄される可能性があります。電源供給が少なかったり高い優先度のプロセスがある場合などに発生します。問題を解決するためにリアルタイム品質のスケーリングが存在します。この記事ではソフトリアルタイムを取り扱っています。ハードリアルタイムは基本的にそこまで必要とされる場合は多くありません。例えば自動車の ABS (アンチロックブレーキシステム) などです。ブレーキが効かなかった場合に二度目はありません。
Power is nothing without control
realtime-lsm モジュールは特定の UID に属するユーザーにさらに強いケイパビリティを手に入れる権限を与えます。rlimit も同じように機能しますが、細かい制御が可能です。ユーザーごと、あるいはグループレベルでケイパビリティを制御することができる新しい機能が PAM には存在します。現在のバージョン (0.80-2) では最初は正しく設定されておらず問題が発生します。PAM を使うことで特定のユーザーや特定のユーザーグループにリアルタイムの優先度を与えることができます。PAM のコンセプトではアプリケーションごとに権限を与えることすら可能となる予定ですが、今のところは不可能となっています。
ヒントとテクニック
PAM が有効なログイン
参照: ログイン時に X を起動。
PAM limits の設定を使用するには pam
が有効になるログイン方法やログインマネージャを使わなければなりません。ほとんど全てのグラフィカルなログインマネージャは pam が有効になっており、Arch のデフォルトログインでも pam
は有効です。/etc/pam.d
を検索することで確認できます:
$ grep pam_limits.so /etc/pam.d/*
何も出力されない場合でも、ログインマネージャ (と PolicyKit) を使っていれば問題ありません。以下のような出力がされるのが理想です:
/etc/pam.d/crond:session required pam_limits.so /etc/pam.d/login:session required pam_limits.so /etc/pam.d/polkit-1:session required pam_limits.so /etc/pam.d/system-auth:session required pam_limits.so /etc/pam.d/system-services:session required pam_limits.so
login
や PolicyKit などは全て pam_limits.so
モジュールを必要とします。これは良いことであり PAM の制限が適用されることを意味します。
コンソール/自動ログイン
参照: 仮想端末に自動ログイン。
グラフィカルログインをしない場合でも、方法はあります。(coreutils に含まれている) su
の pam
を編集してください [1]:
/etc/pam.d/su
... session required pam_limits.so
参考
RLIMIT 定義
- RLIMIT_AS
- プロセスの仮想メモリ (アドレス領域) の最大容量をバイト単位で設定します。brk(2), mmap(2), mremap(2) のコールに影響し、制限を越えると ENOMEM エラーが発生します。また、自動的なスタック拡張も失敗します (SIGSEGV が生成され sigaltstack(2) による別のスタックが利用可能でなければプロセスが kill されます)。RLIMIT_AS の値は long であるため、long が32ビットのマシンでは、制限は最大で 2 GiB であるか、あるいは無制限になります。
- RLIMIT_CORE
- コアファイルの最大容量。0 の場合はコアダンプファイルが作成されません。0 以外の場合、巨大なダンプは指定された容量まで切り詰められます。
- RLIMIT_CPU
- CPU 時間の制限 (秒単位)。プロセスがソフトリミットに達すると、SIGXCPU シグナルが送信されます。このシグナルが送られるとデフォルトではプロセスが終了します。ただし、シグナルをハンドラがキャッチしてメインプログラムに制御を返すこともあります。プロセスが CPU 時間を消費し続ける場合、ハードリミットに達するまで1秒ごとに SIGXCPU が送信され、ハードリミットに達すると SIGKILL が送信されます (Linux 2.2 から 2.6 までの挙動です。ソフトリミットに達しても CPU 時間を浪費し続けるプロセスをどのように扱うかは実装によって変わります。シグナルをキャッチする必要があるポータブルアプリケーションは大抵の場合 SIGXCPU を最初に受け取ったときに終了します)。
- RLIMIT_DATA
- プロセスのデータセグメント (初期化されたデータ・初期化されていないデータ・ヒープ) の最大容量。この制限は brk(2) と sbrk(2) のコールに影響し、リソースのソフトリミットに達すると ENOMEM エラーでコールが失敗します。
- RLIMIT_FSIZE
- プロセスが作成できるファイルの最大容量。この制限を超えてファイルを書き込むと SIGXFSZ シグナルが送信されます。デフォルトではシグナルによってプロセスが終了しますが、プロセスがシグナルをキャッチする場合もあり、その場合は関連するシステムコール (例: write(2), truncate(2)) が EFBIG エラーで失敗します。
- RLIMIT_LOCKS
- (初期の Linux 2.4 のみ) プロセスが作成できる flock(2) のロックと fcntl(2) のリースの合計数を制限します。
- RLIMIT_MEMLOCK
- The maximum number of bytes of memory that may be locked into RAM. In effect this limit is rounded down to the nearest multiple of the system page size. This limit affects mlock(2) and mlockall(2) and the mmap(2) MAP_LOCKED operation. Since Linux 2.6.9 it also affects the shmctl(2) SHM_LOCK operation, where it sets a maximum on the total bytes in shared memory segments (see shmget(2)) that may be locked by the real user ID of the calling process. The shmctl(2) SHM_LOCK locks are accounted for separately from the per-process memory locks established by mlock(2), mlockall(2), and mmap(2) MAP_LOCKED; a process can lock bytes up to this limit in each of these two categories. In Linux kernels before 2.6.9, this limit controlled the amount of memory that could be locked by a privileged process. Since Linux 2.6.9, no limits are placed on the amount of memory that a privileged process may lock, and this limit instead governs the amount of memory that an unprivileged process may lock.
- RLIMIT_MSGQUEUE
- (Linux 2.6.8 以上) Specifies the limit on the number of bytes that can be allocated for POSIX message queues for the real user ID of the calling process. This limit is enforced for mq_open(3). Each message queue that the user creates counts (until it is removed) against this limit according to the formula: bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) + attr.mq_maxmsg * attr.mq_msgsize where attr is the mq_attr structure specified as the fourth argument to mq_open(3). The first addend in the formula, which includes sizeof(struct msg_msg *) (4 bytes on Linux/i386), ensures that the user cannot create an unlimited number of zero-length messages (such messages nevertheless each consume some system memory for bookkeeping overhead).
- RLIMIT_NICE
- (since Linux 2.6.12, but see BUGS below) Specifies a ceiling to which the process’s nice value can be raised using setpriority(2) or nice(2). The actual ceiling for the nice value is calculated as 20 – rlim_cur. (This strangeness occurs because negative numbers cannot be specified as resource limit values, since they typically have special meanings. For example, RLIM_INFINITY typically is the same as -1.)
- RLIMIT_NOFILE
- Specifies a value one greater than the maximum file descriptor number that can be opened by this process. Attempts (open(2), pipe(2), dup(2), etc.) to exceed this limit yield the error EMFILE. (Historically, this limit was named RLIMIT_OFILE on BSD.)
- RLIMIT_NPROC
- The maximum number of processes (or, more precisely on Linux, threads) that can be created for the real user ID of the calling process. Upon encountering this limit, fork(2) fails with the error EAGAIN.
- RLIMIT_RSS
- Specifies the limit (in pages) of the process’s resident set (the number of virtual pages resident in RAM). This limit only has effect in Linux 2.4.x, x < 30, and there only affects calls to madvise(2) specifying MADV_WILLNEED.
- RLIMIT_RTPRIO
- (Since Linux 2.6.12, but see BUGS) Specifies a ceiling on the real-time priority that may be set for this process using sched_setscheduler(2) and sched_setparam(2).
- RLIMIT_RTTIME
- (Since Linux 2.6.25) Specifies a limit on the amount of CPU time that a process scheduled under a real-time scheduling policy may consume without making a blocking system call. For the purpose of this limit, each time a process makes a blocking system call, the count of its consumed CPU time is reset to zero. The CPU time count is not reset if the process continues trying to use the CPU but is preempted, its time slice expires, or it calls sched_yield(2). Upon reaching the soft limit, the process is sent a SIGXCPU signal. If the process catches or ignores this signal and continues consuming CPU time, then SIGXCPU will be generated once each second until the hard limit is reached, at which point the process is sent a SIGKILL signal. The intended use of this limit is to stop a runaway real-time process from locking up the system.
- RLIMIT_SIGPENDING
- (Linux 2.6.8 以上) プロセスを呼び出している実ユーザー ID に対してキューに入れられるシグナルの数の制限を指定します。標準シグナルとリアルタイムシグナルの両方が制限をチェックするときにカウントされます。ただし制限が適用されるのは sigqueue(2) だけです。kill(2) を使用することで常にまだキューに入れられていないシグナルのインスタンスをキューに入れることができます。
- RLIMIT_STACK
- プロセススタックの最大容量 (バイト単位)。上限に達すると、SIGSEGV シグナルが生成されます。このシグナルを処理するには、プロセスは別のシグナルスタック (sigaltstack(2)) を使用しなければなりません。
スケジューリングポリシー
CFS は3つのスケジューリングポリシーを実装しています:
- SCHED_NORMAL (別名 SCHED_OTHER)
- 通常のタスクに使われるスケジューリングポリシー。
- SCHED_BATCH
- 通常のタスクと比べて優先度が低くなり、反応が鈍くなるかわりにタスクを長く動作させてキャッシュをより活用することができます。バッチジョブに適しています。
- SCHED_IDLE
- nice 19 よりも優先度が低くなります。ただしマシンをデッドロックさせるような優先順位の逆転を防ぐために、完全なアイドルタイマースケジューラではありません。
スケジューリングクラス
- IOPRIO_CLASS_RT
- リアルタイム io クラスです。RT スケジューリングクラスは、システムで何が動作しているのかに関わらず、ディスクに対する第一級のアクセス権限を与えられます。そのため RT クラスは注意して使用しないと、他のプロセスに多大な影響を与える可能性があります。ベストエフォートクラスと同じように、スケジューリングウィンドウでどれだけタイムスライスをプロセスに与えるか定義する8つのプライオリティレベルが存在します。RT スケジューリングクラスはシステム内の他のどんなクラスよりも高い優先度を持っているため、RT スケジューリングクラスのプロセスはいかなる時でも真っ先にディスクにアクセスすることができます。将来的には必要なデータレートを指定することで直接適切なパフォーマンスが出せるようになる可能性があります。
- IOPRIO_CLASS_BE
- ベストエフォートのスケジューリングクラスで、特に優先度が設定されていないプロセスのデフォルトになります。プログラムは io の優先度について CPU の nice 設定を継承します。このクラスは 0-7 の優先度を指定でき、低い値ほど優先されます。同じベストエフォート優先度のプログラムはラウンドロビン方式で回されます。クラスデータはプロセスが使用できる io 帯域幅を決定し、大雑把に実装されている cpu の nice レベルに直接マッピングされます。0 が最高の BE レベルで、7 が最低です。cpu の nice 値と io の nice 値は次のようにしてマッピングされます: io_nice = (cpu_nice + 20) / 5。
- IOPRIO_CLASS_IDLE
- アイドルスケジューリングクラスです。このレベルで動作しているプロセスは他のプロセスがディスクを必要としないときだけ io を使用する時間を得ます。アイドル io プロセスは通常のシステムの活動には全く影響を与えません。このスケジューリングクラスは優先度を引数で指定できません。アイドルクラスにクラスデータは存在しません。