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