10.17.2018

Linux C, IPCs, Semaphore, Share Memery and Message Queue

好久沒有記錄一下學習心得了!這一次來記一下Linux系統中的IPC (Inter-Process Communication,內部行程通訊)。

在一個作業系統中有許許多多的行程,程序彼此之間要如何溝通?於是就有了IPC的概念。IPC的方法教課書上有3種:Semaphore (號誌)、Share Memory (共享記憶體)和Message Queue (訊息佇列)。至於Sample Code (程式碼範例)這裡就不寫了,因為參考書上都有,把書上的東西抄過來並沒有什麼意義。這裡只記下一些簡單的學習心得。

1). Semaphore的相關函式為:semctl(); (Semaphore Control), semget(); (Semaphore Get)和semop(); (Semaphore Operation)。

2). Share Memory的相關函式為:shmget(); (Share Memory Get), shmat(); (Share Memory Attach), shmdt(); (Share Memory Delete), shmctl(); (Share Memory Control)。

3). Message Queue的相關函式為:msgctl(); (Message Queue Control), msgget(); (Message Queue Get), msgrcv(); (Message Queue Receive), msgsnd(); (Message Queue Send)。

4). 我們也可以使用一些Linux Command Line來得知這些IPCs的訊息或是刪除它們:ipcs -s; ipcs -m; ipcs -q;
[root@localhost ~]# 
[root@localhost ~]# ipcs -s

------ Semaphore Arrays --------
key                semid            owner            perms            nsems

[root@localhost ~]# 
[root@localhost ~]# ipcs -m
                                                              
------ Shared Memory Segments --------
key        shmid   owner   perms  bytes   nattch   status
0x00000000 131072  root    600    393216   2       dest
0x00000000 163841  root    600    393216   2       dest
0x00000000 65538   gdm     600    393216   2       dest
0x00000000 196611  root    600    393216   2       dest
0x00000000 229380  root    600    393216   2       dest
0x00000000 262149  root    600    393216   2       dest
0x00000000 294918  root    600    393216   2       dest
0x00000000 327687  root    600    393216   2       dest
0x00000000 360456  root    600    393216   2       dest
0x00000000 393225  root    600    393216   2       dest
0x00000000 425994  root    600    393216   2       dest
0x00000000 458763  root    600    393216   2       dest
0x00000000 491532  root    600    393216   2       dest
0x00000000 524301  root    600    393216   2       dest
0x00000000 557070  root    600    393216   2       dest
0x00000000 589839  root    600    393216   2       dest
0x00000000 622608  root    600    393216   2       dest
0x00000000 786451  root    600    393216   2       dest
0x00000000 851989  root    600    393216   2       dest

[root@localhost ~]# 
[root@localhost ~]# ipcs -q

------ Message Queues --------
key              msqid          owner          perms          used-bytes    messages 

[root@localhost ~]# 
[root@localhost ~]# 
或者是,我們執行:cat -n /proc/sysvipc/sem, shm, msg; 也可以查詢到更詳盡的資訊:


如果我們想要手動刪除IPCs的話,指令則是:
ipcsrm -s < sem_id> ; ipcsrm -m < shm_id> ; ipcsrm -q < msg_id> ;

5). 這3種IPCs有何差異 (或是優缺點)?

Semaphore (號誌):
a). 相同的程式要執行2次以上時,可以解決Race Condition (競走現象)的問題。
b). 有提供同步化的保護機制。

Share Memory (共享記憶體):
a). 效率較好,因為是直接對記憶體做存取。
b). 應用於不同的程式 (Process)之間存取相同的記憶體。
c). 缺點為並沒有同步化的機制,需由開發者自行設計。
d). 要避免兩支以上的程序 (Process)同時存取Share Memory的競走現象,可和Semaphore搭配做出保護機制。

Message Queue (訊息佇列):
a). 兩支程式之間可以各自執行,不需同時執行。
b). 承a). 所以並沒有同步化的問題。
c). 缺點每乙則訊息的大小及佇列數量的上限,均有其系統上的限制。

關於IPCs,系統又提供了那些核心參數可供參考?它們的意義為何?

6). Semaphore (號誌):
a). cat -n /proc/sys/kernel/sem
b). sysctl -a | grep --color "kernel.sem"
c). ipcs -s -l
[root@localhost ~]# 
[root@localhost ~]# cat -n /proc/sys/kernel/sem 
        1    250  32000      32    128
[root@localhost ~]# 
[root@localhost ~]# sysctl -a | grep --color "kernel.sem"
kernel.sem = 250        32000      32    128
[root@localhost ~]# 
[root@localhost ~]# ipcs -s -l

------ 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

[root@localhost ~]# 
[root@localhost ~]#
這些指令的執行結果都是一樣地,在/usr/include/linux/sem.h裡都可以找到相對應的值;那這些值代表什意思?

SEMMSL (250): 每一個號誌集合 (陣列)的最大號誌數量 (The maximum semaphores per semaphore set.)。

SEMMNS (32000): 在系統範圍限制上所有號誌集合的總數 (A system-wide limit on the number of semaphores in all semaphore sets.)。

SEMOPM (32): 每一個號誌發生時最大的系統操作數量 (The maximum number of operations that may be specified in a semop(2) call.)。

SEMMNI (128): 在系統範圍限制上最大的號誌集合總數 (A system-wide limit on the maximum number of semaphore identifiers.)。

7). Share Memory (共享記憶體):
a). cat -n /proc/sys/kernel/shmall, shmmax, shmmni
b). sysctl -a | grep --color "kernel.shm"
c). ipcs -m -l
[root@localhost ~]# 
[root@localhost ~]# cat -n /proc/sys/kernel/shmall 
        1    2097152
[root@localhost ~]# 
[root@localhost ~]# cat -n /proc/sys/kernel/shmmax 
        1    33554432
[root@localhost ~]# 
[root@localhost ~]# cat -n /proc/sys/kernel/shmmni
        1    4096
[root@localhost ~]# 
[root@localhost ~]# sysctl -a | grep --color "kernel.shm"
kernel.shmmax = 33554432
kernel.shmall = 2097152
kernel.shmmni = 4096
[root@localhost ~]# 
[root@localhost ~]# ipcs -m -l

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 32768
max total shared memory (kbytes) = 8388608
min seg size (bytes) = 1

[root@localhost ~]# 
這些指令的執行結果都是一樣地,在/usr/include/linux/shm.h裡都可以找到相對應的值;那這些值代表什意思?

SHMALL (2097152): 系統範圍限制上的共享記憶體區塊的大小 (This file contains the system-wide limit on the total number of pages of System V shared memory.)

SHMMAX (33554432): 共享記憶體的最大單位 (bytes) (This file can be used to query and set the run-time limit on the maximum (System V IPC) shared memory segment size that can be created. Shared memory segments up to 1GB are now supported in the kernel. This value defaults to SHMMAX.) (PS: 33,554,432 = 0x02000000)。

SHMMNI (4096): 共享記憶體的最大分割數量 (This file specifies the system-wide maximum number of System V shared memory segments that can be created.)。

SHMMIN (1): 共享記憶體的最小單位 (bytes)。

8). Message Queue (訊息佇列):
a). cat -n /proc/sys/kernel/msgmax, msgmnb, msgmni
b). sysctl -a | grep --color "kernel.msg"
c). ipcs -q -l
[root@localhost ~]# 
[root@localhost ~]# cat -n /proc/sys/kernel/msgmax
        1      8192
[root@localhost ~]# 
[root@localhost ~]# cat -n /proc/sys/kernel/msgmnb
        1      16384
[root@localhost ~]# 
[root@localhost ~]# cat -n /proc/sys/kernel/msgmni
        1      1700
[root@localhost ~]# 
[root@localhost ~]# sysctl -a | grep --color "kernel.msg"
kernel.msgmax = 8192
kernel.msgmni = 1700
kernel.msgmnb = 16384
[root@localhost ~]# 
[root@localhost ~]# ipcs -q -l

------ Messages: Limits --------
max queues system wide = 1700
max size of message (bytes) = 8192
default max size of queue (bytes) = 16384

[root@localhost ~]# 
這些指令的執行結果都是一樣地,在/usr/include/linux/msg.h裡都可以找到相對應的值;那這些值代表什意思?

MSGMAX (8192): 每乙則訊息 (message)的大小 (byte)。

MSGMNI (1700): 在系統範圍限制上的最大佇列 (queue)數目。

MSGMNB (16384): 在系統上所有佇列 (queue)上的訊息 (message)的最大值。

好!就先記到這兒!

沒有留言:

張貼留言