ftp同一主机的多个子进程使用同一个套接字_linux进程通信方式对比
管道:
速度慢,容量有限(64kB,ulimit -a可以查詢的pipe size 指的是一次性寫入的大小限制),只有父子進程能通訊 半雙工的(即數據只能在一個方向上流動)----(匿名管道)
int pipe(int fd[2]); // 返回值:若成功返回0,失敗返回-1
當一個管道建立時,它會創建兩個文件描述符:fd[0]為讀而打開,fd[1]為寫而打開
要關閉管道只需將這兩個文件描述符關閉即可。
單個進程中的管道幾乎沒有任何用處。所以,通常調用 pipe 的進程接著調用 fork,這樣就創建了父進程與子進程之間的 IPC 通道
若要數據流從父進程流向子進程,則關閉父進程的讀端(fd[0])與子進程的寫端(fd[1]);反之,則可以使數據流從子進程流向父進程
FIFO:
任何進程間都能通訊,但速度慢 (命名管道),慢主要是由于內核在讀寫都加了互斥鎖
int mkfifo(const char *pathname, mode_t mode);
FIFO的通信方式類似于在進程中使用文件來傳輸數據,只不過FIFO類型文件同時具有管道的特性。在數據讀出時,FIFO管道中同時清除數據,并且“先進先出”
消息隊列:
容量受到系統限制,且要注意第一次讀的時候,要考慮上一次沒有讀完數據的問題 (優點,解耦,異步,削峰,缺點,中間隊列不能掛掉,消息的重復性)
int msgget(key_t key, int flag); // 創建或打開消息隊列:成功返回隊列ID,失敗返回-1
int msgsnd(int msqid, const void *ptr, size_t size, int flag); // 添加消息:成功返回0,失敗返回-1
int msgrcv(int msqid, void *ptr, size_t size, long type,int flag); // 讀取消息:成功返回消息數據的長度,失敗返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf); // 控制消息隊列:成功返回0,失敗返回-1
在以下兩種情況下,msgget將創建一個新的消息隊列:
如果沒有與鍵值key相對應的消息隊列,并且flag中包含了IPC_CREAT標志位。
key參數為IPC_PRIVATE。
函數msgrcv在讀取消息隊列時,type參數有下面幾種情況:
type == 0,返回隊列中的第一個消息;
type > 0,返回隊列中消息類型為 type 的第一個消息;
type < 0,返回隊列中消息類型值小于或等于 type 絕對值的消息,如果有多個,則取類型值最小的消息。
可以看出,type值非 0 時用于以非先進先出次序讀消息。也可以把 type 看做優先級的權值
信號量:
不能傳遞復雜消息,只能用來同步
int semget(key_t key, int num_sems, int sem_flags); // 創建或獲取一個信號量組:若成功返回信號量集ID,失敗返回-1
int semop(int semid, struct sembuf semoparray[], size_t numops); // 對信號量組進行操作,改變信號量的值:成功返回0,失敗返回-1
int semctl(int semid, int sem_num, int cmd, ...); // 控制信號量的相關信息
共享內存:
能夠很容易控制容量,速度快,但要保持同步,比如一個進程在寫的時候,另一個進程要注意讀寫的問題,相當于線程中的線程安全,當然,共享內存區同樣可以用作線程間通訊,不過沒這個必要,線程間本來就已經共享了同一進程內的一塊內存
int shmget(key_t key, size_t size, int flag); // 創建或獲取一個共享內存:成功返回共享內存ID,失敗返回-1
void *shmat(int shm_id, const void *addr, int flag); // 連接共享內存到當前進程的地址空間:成功返回指向共享內存的指針,失敗返回-1
int shmdt(void *addr); // 斷開與共享內存的連接:成功返回0,失敗返回-1
int shmctl(int shm_id, int cmd, struct shmid_ds *buf); // 控制共享內存的相關信息:成功返回0,失敗返回-1
二者本質上是類似的,mmap可以看到文件的實體,而 shmget 對應的文件在交換分區上的 shm 文件系統內,無法直接 cat 查看
ipcs -m查看使用的共享內存
/proc/sys/kernel/shmmax 限制了共享內存的最大值
安全性:mmap 方式對應的真實文件,如果用戶有權限即可查看,甚至刪除 shmget 方式其實也一樣,好了一層皮罷了(ipcrm -m …)
一致性:mmap 方式下各進程映射文件的相同部分可以共享內存 shmget時各個進程共享同一片內存區 不建議使用交疊的方式使用 mmap
持續性:進程掛了重啟不丟失內容,二者都可以做到 機器掛了重啟,mmap 可以不丟失內容(文件內保存了OS同步過的映像),而 shmget 會丟失
易用性:mmap 的接口會簡單一些
通用性:posix 的 mmap 會相對廣泛一些
其他:mmap在某些內核版本下會頻繁讀寫磁盤,需要注意一下
共享內存的通信需要注意一個鎖的問題,多個進程讀取同一塊內存,必然是需要同步加鎖,這個時候很多人會選擇使用互斥鎖,使用互斥鎖要是在加鎖后進程crash,那這塊共享內存就廢了,互斥鎖是只有加鎖的線程才能釋放,其他線程釋放不了,在這里可以使用文件鎖是個不錯的選擇,因為文件鎖在進程crash時,操作系統會清理掉,若有其他更好的方式歡迎留言區留言一起探討一下
套接字
以上各種底層通信方式都是居于進程部署到同一臺物理機的,套接字是唯一一種支持不同主機通信的方式(rpc除外,這個只是在socket上封裝的一層調用)
總結
以上是生活随笔為你收集整理的ftp同一主机的多个子进程使用同一个套接字_linux进程通信方式对比的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python小白的数学建模课-03.线性
- 下一篇: Python小白的数学建模课-17.条件