プログラムで何度もshmgetを呼び出して、平均サイズ85840バイトのshmを取得します。私は約32771 shmを取得しましたが、shmgetはshmを返しませんが、「デバイスにスペースが残っていません」というエラーが返されます。
カーネルの制限を次のように増やしました。
$ sysctl -A|grep shm
kernel.shmmax = 33554432
kernel.shmall = 1677721600
kernel.shmmni = 409600
しかし、まだ問題が発生します。どうして?
/etc/security/limits.confにも何かを入れる必要がありますか?プログラムはshmsとほぼ同じ数のファイルも開くため、「user-nofile 1000000」しかありません。
これは無料の出力です
$ free
total used free shared buffers cached
Mem: 8150236 7261676 888560 0 488100 3270792
-/+ buffers/cache: 3502784 4647452
Swap: 12287992 554692 11733300
そしてipcs
$ ipcs -lm
------ Shared Memory Limits --------
max number of segments = 409600
max seg size (kbytes) = 1638400
max total shared memory (kbytes) = 6710886400
min seg size (bytes) = 1
Shmはスワップアウトできると思いますので、十分なスペースがあるはずです。
カーネルではshmmniは32768に制限されています。
#define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
ファイル...version.../include/linux/ipc.h
。
カーネルの再コンパイルが不足しているため、これは共有メモリセグメントの数のハード制限です。
使用する ipcs -l
実際に有効な制限を確認し、ipcs -a
およびipcs -m
を使用して何が使用されているかを確認し、出力を比較できるようにします。 nattch
列を見てください。プロセスが終了したときに削除されなかった、プロセスがアタッチされていないセグメントはありますか(通常、プログラムがクラッシュしたことを意味します)? ipcrm
はそれらをクリアできますが、これがテストマシンである場合は、再起動が速くなります(制限への変更が確実に反映されるようになります)。
カーネルパラメータがおかしいようです。特に、shmall
はバイト数ではなくページ数であり、4kBがデフォルトのページサイズです(実行getconf PAGESIZE
を使用して、使用しているものを確認します)。 RAM)は何テラバイトありますか?
ここで、約32771の共有メモリセグメントを取得するとします。これは、約32768(または2から15)でもあり、符号付き16ビット整数が制限要因であることを示唆しています。そして、どのカーネルを実行していますか(これには独自の制限があるため)? 2つは関連している可能性があります。
shmget()
が新しい共有メモリセグメントを割り当て、それらの多くを使用しているように(limits.confを考慮して)、共有メモリセグメントを使用しすぎている可能性はありませんか? shmget()
の呼び出しの経験はあまりありませんが、開いている可能性のあるファイルの数(1000000)が、許可されている共有メモリセグメント(SHMMNI)の数である409600よりも多いようです。