1. 概要

ご存知のように、プロセスは現在実行中のプログラムですが、スレッドはセミプロセスまたは軽量プロセスです。

このチュートリアルでは、マルチスレッドプロセスとは何かについて説明します。 また、Linuxでプロセスあたりのスレッド数に制限がある理由とその制限についても学習します。

2. マルチスレッドプロセスとは何ですか?

共有メモリ空間の同じプログラム内で実行の複数のスレッドを提供することは、マルチスレッドと呼ばれます。

マルチスレッドプロセスにより、複数のスレッドを同時に実行できます。 マルチスレッドの目的は、パフォーマンスを向上させることです。

最適なパフォーマンスを実現するために、Linuxにはスレッド数の制限があります。  threads-max カーネルパラメーターを設定して、プロセスあたりのスレッド数が常にその制限以下になるようにすることができます。 ただし、仮想メモリの量やスタックサイズなどの他の要因によって、プロセスに割り当てられるスレッドの数が間接的に決まる場合があります。

3. プロセスあたりのスレッド数の制限

Linuxには、プロセスあたりの最大スレッド数の設定があります。これは、プロセスが処理できる同時実行の最大数を指定します

これを変更すると、プロセスが抑制され、実行の待ち時間が最小限に抑えられます。

この制限に達するということは、プロセスがピーク負荷時にその数のスレッドを必要とすることを意味します。 ただし、要求をタイムリーに処理できる限り、プロセスは適切に調整されます。

ただし、制限に達すると、スレッドがキューに入れられ、プロセスが過負荷になる可能性があります。 この時点で、プロセスは、アクティブなスレッドの数が制限を下回るまで、新しいスレッドの作成を延期します。

4. 最大スレッド数を取得する方法

カーネルパラメータthreads-max は、スレッドの最大数を制御します。

このパラメーターは、ファイル / proc / sys / kernel /threads-maxで定義されています。

catコマンドを使用してこのファイルを表示してみましょう。

$ cat /proc/sys/kernel/threads-max
63704

ここで、出力63704は、カーネルが最大63,704スレッドを実行できることを示しています。

または、sysctlコマンドを使用してthreads-max値を取得することもできます。

$ sysctl -a | grep threads-max
kernel.threads-max = 63704

kernel.pid_maxvm.max_map_countは、ピーク負荷時に新しいスレッドの作成をブロックする他の2つの制限を指定します。

pid_max パラメーターは、PIDがラップアラウンドする値を指定します。

$ cat /proc/sys/kernel/pid_max 
131072

上記の131072のkernel.pid_max値は、カーネルが最大131,072プロセスを同時に実行できることを意味します。

max_map_count パラメーターは、プロセスが所有できる仮想メモリ領域(VMA)の最大数を指定します。

$ cat /proc/sys/vm/max_map_count
65530

上記の65530のvm.max_map_count値は、プロセスが持つことができるメモリマップ領域の最大数です。

Linuxカーネルは、プロセスとスレッドの両方を同じ方法で処理します。 したがって、プロセスの数を制限する値は、間接的にスレッドの数も制限します

したがって、 kernel.pid_max は、同時スレッドおよびプロセスの総数よりも大きくする必要があります。

スレッドが多いと、サーバーが機能するにはメモリを消費しすぎる可能性があります。 vm.max_map_count は、仮想メモリと、独自のプライベートスタックを設定するためにこのメモリを必要とするスレッドの数の両方を制限します。

systemd システムでは、cgroup pids.maxパラメーターが別の制限を適用します。 これはデフォルトで12,288に設定されています。 場合によっては、このデフォルトのリソース制限では不十分であるか、制限が多すぎる可能性があります。

または、systemdのTasksMax設定の一部で特定の調整を実行すると便利な場合があります。 /etc/systemd/logind.conf[Login]セクションのUserTasksMaxパラメーターは、デフォルトの制限をオーバーライドします。

$ grep -i "^UserTasksMax" /etc/systemd/logind.conf
UserTasksMax=50000

これはまさに、systemdがログインシェルから実行されるプログラムにスレッド制限を適用する方法です。

5. 最大スレッド数を設定する方法

プロセスごとのスレッドの最大数の値を設定するには、いくつかの方法があります。 これらの値は、プロセスで許可されるスレッドの数を決定します。

実行時にthreads-maxカーネルパラメータを一時的に設定しましょう。

$ echo 120000 > /proc/sys/kernel/threads-max

恒久的に設定することができます kernel.threads-max 追加することによるパラメータ kernel.threads-max = /etc/sysctl.conf ファイル:

$ sysctl -w kernel.threads-max=120000 >> /etc/sysctl.conf

次に、 pid_max パラメーターを200000に設定すると、カーネルは最大200,000のプロセスを同時に実行できます。

$ echo 200000 > /proc/sys/kernel/pid_max

同様に、 max_map_count パラメーターを600000に設定すると、プロセスは最大600,000個の仮想メモリ領域(VMA)を所有できます。

$ echo 600000 > /proc/sys/vm/max_map_count

systemd システムでは、UserTasksMaxはすべてのユーザーのTasksMax設定を指定し、スレッド制限を決定します。

$ sed -i "s/^UserTasksMax/#UserTasksMax/" /etc/systemd/system.conf
$ echo "UserTasksMax=60000" >> /etc/systemd/system.conf
$ grep -i "UserTasksMax" /etc/systemd/logind.conf
#UserTasksMax=50000
UserTasksMax=60000

6. 最大スレッド数に影響を与える要因

プロセスあたりのスレッド数に制限を設定するシステムパラメータがありますが、OSとメモリがそのかなり前に制限要因になる可能性があります。

プロセスが持つことができるスレッド数の制限は、次の式を使用して計算されます。

スレッド数=合計仮想メモリ/(スタックサイズ* 1024 * 1024)

したがって、合計仮想メモリを増やすことにより、プロセスあたりのスレッド数を増やすことができます。 スレッドあたりのスタックサイズの量は、他の何よりも制限になる可能性が高くなります。 スレッドごとのスタックサイズを減らすことは、スレッドの総数を増やす方法でもあります。

ulimit を使用して、スレッドごとのスタックサイズを確認できます。

$ ulimit -a | grep "stack size"
stack size              (kbytes, -s) 10240

この値は、各スレッドがスタックに割り当てられたこの量のメモリ(10MB)を取得することを意味します。 32ビットプログラムと4GBの最大アドレス空間では、スレッドの最大数は次のようになります。

4096MB / 10MB = 409

64ビットプロセッサでは、ulimitを使用してスレッドごとのスタックサイズを調整できます。

$ ulimit -s 8192

7. 結論

この記事では、Linuxのマルチスレッドプロセスとは何かを理解しました。 また、Linuxでのプロセス数あたりの最大スレッド数の重要性についても学びました。 最後に、プロセス数ごとに最大スレッドを取得して設定する方法と、それに影響を与える要因について説明しました。