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)的最大值。

好!就先記到這兒!

沒有留言:

張貼留言