多進程間通信的技術手段包括共享內存、消息隊列、信號量等等,Linux系統下的ipcs是一個極好的工具,可以查看當前系統以上三項的使用情況,從而利於定位多進程通信中出現的通信問題。
root@doufupic11a ~]# ipcs -h Usage: ipcs [resource ...] [output-format] ipcs [resource] -i <id> Options: -i, --id <id> print details on resource identified by id -h, --help display this help and exit -V, --version output version information and exit Resource options: -m, --shmems shared memory segments -q, --queues message queues -s, --semaphores semaphores -a, --all all (default) Output format: -t, --time show attach, detach and change times -p, --pid show creator and last operations PIDs -c, --creator show creator and owner -l, --limits show resource limits -u, --summary show status summary --human show sizes in human readable format -b, --bytes show sizes in bytes
ipcs -a命令可以查看當前使用的共享內存、消息隊列及信號量所有信息,對於該選項對應的結果,介紹以下幾個部分:
1、信號量在創建時分信號量集和信號量的概念,該命令的查詢結果中,Semaphore Arrays下面每一行代表一個信號量集,其中perms對應信號量集的權限,nsems對應信號量集中信號量的個數,對於信號量集的創建方法可以查詢semctl相關的函數使用方法。
1、信號量在創建時分信號量集和信號量的概念,該命令的查詢結果中,Semaphore Arrays下面每一行代表一個信號量集,其中perms對應信號量集的權限,nsems對應信號量集中信號量的個數,對於信號量集的創建方法可以查詢semctl相關的函數使用方法。
2、對於消息隊列Message Queues而言,可以看到msqid對應創建隊列時得到的id值,從messages中可以看到當前隊列中存在的消息個數,從used_bytes中可以看到當前所有消息占用的字節數,所以單個消息的字節數則為總字節數除以消息數,同時如果消息個數不為零則說明消息隊列中的消息沒有得到及時處理,可以據此判斷是否存在隊列阻塞的風險。
[root@doufupic11a ~]# ipcs -a ------ Message Queues -------- key msqid owner perms used-bytes messages ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00004dc4 65536 sapadm 760 40141728 1 0x00004dbe 98305 root 777 637620 1 0x00000000 655362 root 600 524288 2 dest 0x00000000 557059 root 600 524288 2 dest 0x00000000 753668 root 600 16777216 2 dest 0x00000000 786437 root 600 524288 2 dest 0x00000000 819206 root 600 524288 2 dest ------ Semaphore Arrays -------- key semid owner perms nsems 0x0000752f 98304 sapadm 777 5
ipcs -p命令可以得到與共享內存、消息隊列相關進程之間的消息。對於此選項,有如下介紹:
1、從該命令結果中可以看到Message Queues PIDs中的msqid既對應上條命令結果中的消息隊列id,根據id則可以獲取到lspid、lrpid消息,其中lspid代表最近一次向消息隊列中發送消息的“進程號”,lrpid對應最近一次從消息隊列中讀取消息的“進程號”。但請注意:此處的進程號是弱進程號,既它有可能代表的是線程號,如果進程中是起的線程對消息隊列發送、接收消息,則此處pid對應的均是線程號。可以采用ps -AL | grep pid來查找該線程對應的進程id。
1、從該命令結果中可以看到Message Queues PIDs中的msqid既對應上條命令結果中的消息隊列id,根據id則可以獲取到lspid、lrpid消息,其中lspid代表最近一次向消息隊列中發送消息的“進程號”,lrpid對應最近一次從消息隊列中讀取消息的“進程號”。但請注意:此處的進程號是弱進程號,既它有可能代表的是線程號,如果進程中是起的線程對消息隊列發送、接收消息,則此處pid對應的均是線程號。可以采用ps -AL | grep pid來查找該線程對應的進程id。
[root@doufupic11a ~]# ipcs -p ------ Message Queues PIDs -------- msqid owner lspid lrpid ------ Shared Memory Creator/Last-op PIDs -------- shmid owner cpid lpid 65536 sapadm 13321 13321 98305 root 13407 23585 655362 root 22847 13297 557059 root 22812 13297 753668 root 23061 23075 786437 root 22584 13297 819206 root 22847 13297
ipcs -u命令可以查看各個資源的使用總結信息,其中可以看到使用的信號量集的個數、信號量的個數,以及消息隊列中當前使用的消息個數總數、占用的空間字節數
[root@doufupic11a ~]# ipcs -u ------ Messages Status -------- allocated queues = 0 used headers = 0 used space = 0 bytes ------ Shared Memory Status -------- segments allocated 7 pages allocated 14565 pages resident 10623 pages swapped 0 Swap performance: 0 attempts 0 successes ------ Semaphore Status -------- used arrays = 1 allocated semaphores = 5
ipcs -l命令可以查看各個資源的系統限制信息,可以看到系統允許的最大信號量集及信號量個數限制、最大的消息隊列中消息個數等信息。
1、從中可以看到以下信號量的限制信息,其中信號量集最大個數為128、每個信號量集中信號量最大個數為250、所有信號量最大個數為32000、每個信號量可以被同時調用的次數為32,這些參數是linux系統下的默認參數,對於限制參數也可以做一定程度的優化,會有一定程度上性能的提升,具體優化方法可以搜索相關帖子。
[root@doufupic11a~]# ipcs -l ------ Messages Limits -------- max queues system wide = 32768 max size of message (bytes) = 8192 default max size of queue (bytes) = 16384 ------ Shared Memory Limits -------- max number of segments = 32768 max seg size (kbytes) = 18014398509481983 max total shared memory (kbytes) = 18014398442373116 min seg size (bytes) = 1 ------ Semaphore Limits -------- max number of arrays = 128 max semaphores per array = 250 max semaphores system wide = 32000 max ops per semop call = 32 semaphore max value = 32767
對應的參數文件/etc/sysctl.conf
cat /etc/sysctl.conf|grep -v ^#|grep -v ^$ fs.file-max=20000000 fs.aio-max-nr=18446744073709551615 vm.memory_failure_early_kill=1 kernel.shmmax=18446744073709551615 kernel.shmmni=32768 vm.max_map_count=2147483647
ipcrm
ipcrm -h Usage: ipcrm [options] ipcrm <shm|msg|sem> <id> [...] Options: -m, --shmem-id <id> remove shared memory segment by shmid -M, --shmem-key <key> remove shared memory segment by key -q, --queue-id <id> remove message queue by id -Q, --queue-key <key> remove message queue by key -s, --semaphore-id <id> remove semaphore by id -S, --semaphore-key <key> remove semaphore by key -a, --all[=<shm|msg|sem>] remove all -v, --verbose explain what is being done -h, --help display this help and exit -V, --version output version information and exit