亚洲综合图片区自拍_思思91精品国产综合在线观看_一区二区三区欧美_欧美黑人又粗又大_亚洲人成精品久久久久桥本

Linux下進(jìn)程間如何實(shí)現(xiàn)共享內(nèi)存通信 天天微動態(tài)

2023-04-26 17:05:23 來源:Linux兵工廠

這次我們來講一下Linux進(jìn)程通信中重要的通信方式:共享內(nèi)存作為Linux軟件開發(fā)攻城獅,進(jìn)程間通信是必須熟練掌握的重要技能,而共享內(nèi)存是在程序開發(fā)中常用的也是重要的一種進(jìn)程間通信方式。

下面我們就來聊一聊Linux下進(jìn)程間如何實(shí)現(xiàn)共享內(nèi)存通信,有哪些方式?

1、基本概念

UNIX 和 Linux

UNIX和Linux是兩種不同的操作系統(tǒng),它們的主要區(qū)別在以下幾個方面:


(資料圖片)

歷史:UNIX是最早的商業(yè)化操作系統(tǒng)之一,最初由貝爾實(shí)驗(yàn)室開發(fā),而Linux則是由Linus Torvalds于1991年開發(fā)的開源操作系統(tǒng)。源代碼:UNIX的源代碼是私有的,需要購買授權(quán)才能使用和修改,而Linux是開源的,任何人都可以自由地訪問、使用和修改其源代碼??梢浦残裕河捎赨NIX的代碼是私有的,因此它們在不同的硬件平臺之間的可移植性較差。 而Linux的源代碼是開放的,因此它可以在多種硬件平臺上運(yùn)行。發(fā)行版:UNIX有多個商業(yè)和非商業(yè)版本,如Solaris、AIX、HP-UX等,每個版本都有自己的特點(diǎn)和功能。 而Linux則有許多不同的發(fā)行版,如Ubuntu、Debian、Red Hat、Fedora等。命令行工具:UNIX和Linux有許多相同的命令行工具和命令,如ls、grep、awk等,但也有一些不同之處。

總的來說,UNIX和Linux都是基于UNIX哲學(xué)的操作系統(tǒng),但它們在源代碼、可移植性、發(fā)行版和命令行工具等方面有所不同。

System V 和 POSIX

System V和POSIX是兩種不同的操作系統(tǒng)標(biāo)準(zhǔn),它們的區(qū)別在以下幾個方面:

歷史背景:System V最初是由AT&T開發(fā)的UNIX版本,而POSIX是IEEE為了保證不同UNIX系統(tǒng)的兼容性而開發(fā)的標(biāo)準(zhǔn)。體系結(jié)構(gòu):System V是一種具體的操作系統(tǒng),而POSIX則是一種操作系統(tǒng)接口標(biāo)準(zhǔn)。 因此,System V具有更多的操作系統(tǒng)特定功能,而POSIX的接口更為通用,適用于多種不同類型的UNIX系統(tǒng)。文件系統(tǒng):System V和POSIX的文件系統(tǒng)不同。 System V使用名為“inode”的數(shù)據(jù)結(jié)構(gòu)來描述文件和目錄,而POSIX則使用名為“文件描述符”的整數(shù)來表示打開的文件。Shell:System V和POSIX的Shell也不同。 System V的Shell是Bourne Shell,而POSIX的Shell是Bourne-Again Shell(bash)。網(wǎng)絡(luò)支持:System V和POSIX的網(wǎng)絡(luò)支持也不同。 System V使用TCP/IP協(xié)議棧,而POSIX使用套接字(socket)接口。

2、System V IPC 和 POSIX IPC

System V IPC(Interprocess Communication)和POSIX IPC都是用于在不同進(jìn)程間進(jìn)行通信的機(jī)制,但它們之間有幾個區(qū)別:

編程接口:System V IPC和POSIX IPC的編程接口不同。 System V IPC使用IPC對象(如信號量、共享內(nèi)存和消息隊(duì)列)來實(shí)現(xiàn)進(jìn)程間通信,而POSIX IPC使用命名對象(如命名信號量、命名共享內(nèi)存和命名管道)??梢浦残裕篜OSIX IPC是由IEEE POSIX標(biāo)準(zhǔn)定義的,因此POSIX IPC是可移植的,可在不同的操作系統(tǒng)上使用。 而System V IPC是由System V操作系統(tǒng)提供的,因此不同的操作系統(tǒng)可能實(shí)現(xiàn)不同,因此在跨平臺時可能會有問題。接口和實(shí)現(xiàn):System V IPC的接口和實(shí)現(xiàn)是緊密耦合的,而POSIX IPC的接口和實(shí)現(xiàn)是松散耦合的。 這意味著在POSIX IPC中,接口和實(shí)現(xiàn)是獨(dú)立的,因此可以在實(shí)現(xiàn)中進(jìn)行更改,而不影響接口,這使得在不同的系統(tǒng)上實(shí)現(xiàn)相同的接口變得更容易。特性:System V IPC提供的特性比POSIX IPC多,例如,System V IPC提供了消息隊(duì)列,而POSIX IPC則沒有。 另一方面,POSIX IPC提供了諸如命名管道之類的特性,而System V IPC則沒有。

綜上所述,System V IPC和POSIX IPC都有其優(yōu)點(diǎn)和缺點(diǎn)。 在選擇使用哪種IPC機(jī)制時,需要根據(jù)具體應(yīng)用場景和需求進(jìn)行權(quán)衡。

3、共享內(nèi)存實(shí)現(xiàn)方式

在Linux下,共享內(nèi)存可以使用System V IPC機(jī)制或POSIX IPC機(jī)制實(shí)現(xiàn)。

使用System V IPC機(jī)制:

使用shmget()函數(shù)創(chuàng)建共享內(nèi)存區(qū)域并獲取其標(biāo)識符。 使用shmat()函數(shù)將共享內(nèi)存區(qū)域附加到進(jìn)程地址空間中。 使用shmdt()函數(shù)將共享內(nèi)存區(qū)域從進(jìn)程地址空間中分離。 使用shmctl()函數(shù)控制共享內(nèi)存區(qū)域的屬性和狀態(tài)。

使用POSIX IPC機(jī)制:

使用shm_open()函數(shù)創(chuàng)建共享內(nèi)存區(qū)域并獲取其文件描述符。 使用ftruncate()函數(shù)調(diào)整共享內(nèi)存區(qū)域的大小。 使用mmap()函數(shù)將共享內(nèi)存區(qū)域映射到進(jìn)程地址空間中。 使用munmap()函數(shù)解除共享內(nèi)存區(qū)域與進(jìn)程地址空間的映射關(guān)系。 使用shm_unlink()函數(shù)刪除共享內(nèi)存區(qū)域的文件名并釋放資源。

System V IPC機(jī)制實(shí)現(xiàn)共享內(nèi)存

以下是一個使用System V IPC機(jī)制實(shí)現(xiàn)共享內(nèi)存的簡單例程,它展示了如何創(chuàng)建、附加和分離共享內(nèi)存區(qū)域。

#include #include #include #include #include #define SHM_SIZE 1024 // 共享內(nèi)存大小int main() {    int shmid;    char *shmaddr;    char s8ReadBuf[1024] = {0};    key_t key = ftok(".", "s"); // 獲取共享內(nèi)存標(biāo)識符    if (key == -1) {        perror("ftok");        exit(1);    }    // 創(chuàng)建共享內(nèi)存區(qū)域    shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);    if (shmid == -1) {        perror("shmget");        exit(1);    }    // 將共享內(nèi)存區(qū)域附加到進(jìn)程地址空間中    shmaddr = shmat(shmid, NULL, 0);    if (shmaddr == (char *) -1) {        perror("shmat");        exit(1);    }#if 1    // 在共享內(nèi)存中寫入數(shù)據(jù)    strncpy(shmaddr, "Hello, world!", SHM_SIZE);#else    // 讀數(shù)據(jù)    // memcpy(s8ReadBuf, shmaddr, 1024);    // printf("s8ReadBuf:%s\\n", s8ReadBuf);#endif    // 分離共享內(nèi)存區(qū)域    if (shmdt(shmaddr) == -1) {        perror("shmdt");        exit(1);    }    return 0;}

在上面的例程中,我們首先使用ftok()函數(shù)生成一個key值作為共享內(nèi)存的標(biāo)識符。 然后使用shmget()函數(shù)創(chuàng)建共享內(nèi)存區(qū)域,shmaddr指向共享內(nèi)存區(qū)域的起始地址。 最后使用shmdt()函數(shù)分離共享內(nèi)存區(qū)域。

POSIX IPC機(jī)制實(shí)現(xiàn)共享內(nèi)存

以下是一個使用POSIX IPC機(jī)制實(shí)現(xiàn)共享內(nèi)存的簡單例程,它展示了如何創(chuàng)建、映射和解除映射共享內(nèi)存區(qū)域。

#include #include #include #include #include #include #define SHM_SIZE 1024 // 共享內(nèi)存大小#define SHM_NAME "/myshm" // 共享內(nèi)存名稱int main() {    int fd;    char *shmaddr;    char s8ReadBuf[1024] = {0};    const char *msg = "Hello, world!";    // 創(chuàng)建共享內(nèi)存區(qū)域    fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);    if (fd == -1) {        perror("shm_open");        exit(1);    }    // 調(diào)整共享內(nèi)存區(qū)域的大小    if (ftruncate(fd, SHM_SIZE) == -1) {        perror("ftruncate");        exit(1);    }    // 映射共享內(nèi)存區(qū)域到進(jìn)程地址空間中    shmaddr = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);    if (shmaddr == MAP_FAILED) {        perror("mmap");        exit(1);    }#if 1    // 在共享內(nèi)存中寫入數(shù)據(jù)    strncpy(shmaddr, msg, SHM_SIZE);#else    // 讀數(shù)據(jù)    // memcpy(s8ReadBuf, shmaddr, 1024);    // printf("s8ReadBuf:%s\\n", s8ReadBuf);#endif    // 解除共享內(nèi)存區(qū)域與進(jìn)程地址空間的映射關(guān)系    if (munmap(shmaddr, SHM_SIZE) == -1) {        perror("munmap");        exit(1);    }    // 刪除共享內(nèi)存區(qū)域的文件名并釋放資源    if (shm_unlink(SHM_NAME) == -1) {        perror("shm_unlink");        exit(1);    }    return 0;}

在上面的例程中,我們使用shm_open()函數(shù)創(chuàng)建一個共享內(nèi)存區(qū)域,然后使用ftruncate()函數(shù)調(diào)整共享內(nèi)存區(qū)域的大小。 接著,我們使用mmap()函數(shù)將共享內(nèi)存區(qū)域映射到進(jìn)程地址空間中,并使用strncpy()函數(shù)在共享內(nèi)存中寫入數(shù)據(jù)。 最后,我們使用munmap()函數(shù)解除共享內(nèi)存區(qū)域與進(jìn)程地址空間的映射關(guān)系,并使用shm_unlink()函數(shù)刪除共享內(nèi)存區(qū)域的文件名并釋放資源。

小結(jié)

通過上面的示例希望對小伙伴們在共享內(nèi)存通信編程中有所幫助,學(xué)會如何使用共享內(nèi)存通信,并靈活運(yùn)用于日常的編程中。 共享內(nèi)存方式的通信必須熟練掌握與應(yīng)用。

標(biāo)簽:

上一篇:觀天下!EMC小知識學(xué)習(xí)筆記
下一篇:最后一頁