Linux进程间的通信----->共享内存
共享內(nèi)存:
????????顧名思義,共享內(nèi)存就是允許兩個(gè)不相關(guān)的進(jìn)程訪問(wèn)同一個(gè)邏輯內(nèi)存。共享內(nèi)存是在兩個(gè)正在運(yùn)行的進(jìn)程之間共享和傳遞數(shù)據(jù)的一種非常有效的方式。不同進(jìn)程之間共享的內(nèi)存通常安排為同一段物理內(nèi)存。進(jìn)程可以將同一段共享內(nèi)存連接到它們自己的地址空間中,所有進(jìn)程都可以訪問(wèn)共享內(nèi)存中的地址,就好像它們是由用C語(yǔ)言函數(shù)malloc分配的內(nèi)存一樣。而如果某個(gè)進(jìn)程向共享內(nèi)存寫入數(shù)據(jù),所做的改動(dòng)將立即影響到可以訪問(wèn)同一段共享內(nèi)存的任何其他進(jìn)程。(取自博客一位大哥-->Linux進(jìn)程間通信——使用共享內(nèi)存_tianmo2010的專欄-CSDN博客)
創(chuàng)建虛擬內(nèi)存之后返回的地址空間屬于用戶空間, 不同進(jìn)程可以將同一物理內(nèi)存區(qū)域映射到各自的用戶空間中
?知道共享內(nèi)存的原理之后,開(kāi)始代碼實(shí)現(xiàn):
**首先創(chuàng)建共享內(nèi)存:
int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);
//1234這個(gè)可以隨意給 只要是大于0的32位整數(shù)就好
//128是共享內(nèi)存空間大小
//IPC_CREAT是創(chuàng)建共享內(nèi)存的命令 0600是權(quán)限
**第一次創(chuàng)建完共享內(nèi)存時(shí),它還不能被任何進(jìn)程訪問(wèn),shmat()函數(shù)的作用就是用來(lái)啟動(dòng)對(duì)該共享內(nèi)存的訪問(wèn),并把共享內(nèi)存連接到當(dāng)前進(jìn)程的地址空間。
char *s = (char*)shmat(shmid,NULL,0);
//shmid就是上面shmget之后的返回值int shmid
shmat函數(shù)原型:
?如上圖所示shmat中第二個(gè)參數(shù)為空:如果為空的話,由系統(tǒng)選擇一個(gè)合適的進(jìn)程地址
?然后shmat中第三個(gè)int shmflg置為零是他要是為0? ?讀和寫的權(quán)限都有的
**然后斷開(kāi)映射 (這塊斷開(kāi)映射可有可無(wú),因?yàn)檫M(jìn)程結(jié)束后,自動(dòng)就斷開(kāi)映射了)
shmdt(s);
//s是上述共享內(nèi)存的地址
代碼統(tǒng)一起來(lái)實(shí)現(xiàn):
進(jìn)程shma.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/shm.h>int main()
{int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);assert(shmid != -1);char *s = (char*)shmat(shmid,NULL,0);while(1){printf("input : \n");char buff[128] = {0};fgets(buff,128,stdin);strcpy(s,buff);//向共享內(nèi)存s中寫入數(shù)據(jù)if(strncmp(buff,"end",3) == 0){break;}}shmdt(s);
}
shmb.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/shm.h>int main()
{int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);assert(shmid != -1);char *s = (char*)shmat(shmid,NULL,0);while(1){ if(strncmp(s,"end",3) == 0){break;}printf("read: %s\n",s);sleep(1);}shmdt(s);
}
ok? 來(lái)看運(yùn)行結(jié)果:在輸入端shma.c中輸入abc? 然后輸出端shmb.c就會(huì)不停的打出abc? 直到shma.c輸入end結(jié)束輸入端? 它才會(huì)停止打印abc
?那么遇到這種情況該怎么辦呢?前面一篇博客我寫過(guò) :凡是想讓進(jìn)程依次運(yùn)行最好的辦法就是信號(hào)量Linux編程題:信號(hào)量同步三進(jìn)程依次打印若干次ABC_神廚小福貴!的博客-CSDN博客和這個(gè)是類似的問(wèn)題
然后下面進(jìn)行信號(hào)量的同步這兩進(jìn)程:實(shí)現(xiàn)原理
下面所使用的sem.c? ?sem.h這些文件都在:我的另一篇博客中:
Linux編程題:信號(hào)量同步三進(jìn)程依次打印若干次ABC_神廚小福貴!的博客-CSDN博客三個(gè)進(jìn)程依次打印ABC.....思路及大致流程如下:思路取自這位大哥:Linux編程題:創(chuàng)建3個(gè)線程分別打印abc,用信號(hào)量進(jìn)行同步_cleverlemon的博客-CSDN博客這位大哥寫的是線程,不需要自己封裝sem那些初始化函數(shù),pv操作函數(shù)以及銷毀函數(shù),這篇寫的是多進(jìn)程,麻煩一些,大致思路一毛一樣來(lái)看代碼實(shí)現(xiàn):先來(lái)對(duì)sem所需的初始化函數(shù),pv操作函數(shù),銷毀函數(shù)進(jìn)行封裝:sem.h#include <stdio.h>#include <stdl.https://blog.csdn.net/qq_45829112/article/details/121222304??
代碼實(shí)現(xiàn):shma.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/shm.h>
#include "sem.h"int main()
{int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);assert(shmid != -1);char *s = (char*)shmat(shmid,NULL,0);sem_init();while(1){printf("input : \n");char buff[128] = {0};fgets(buff,128,stdin);sem_p(SEM1); strcpy(s,buff);//向共享內(nèi)存s中寫入數(shù)據(jù)sem_v(SEM2);if(strncmp(buff,"end",3) == 0){break;}}shmdt(s);
}
shmb.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/shm.h>
#include "sem.h"int main()
{int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);assert(shmid != -1);char *s = (char*)shmat(shmid,NULL,0);sem_init();while(1){ sem_p(SEM2);if(strncmp(s,"end",3) == 0){break;}printf("read: %s\n",s);sleep(1);}shmdt(s);sem_destroy(); //該程序是最后退出的 由該程序完成信號(hào)量的銷毀
}
然后進(jìn)行可執(zhí)行程序的編譯鏈接:
?看運(yùn)行結(jié)果:
?該程序的難點(diǎn)在于僅僅使用共享內(nèi)存進(jìn)行通信的時(shí)候,輸出輸入達(dá)不到預(yù)期效果(也就是輸出端一直打印同一個(gè)值),這時(shí)候就得想到使用信號(hào)量來(lái)同步兩個(gè)進(jìn)程,來(lái)使得兩進(jìn)程可以達(dá)到通信的效果!
“能看到這里的親兄弟們,都是認(rèn)真上進(jìn)的親兄弟,加油!!!”
總結(jié)
以上是生活随笔為你收集整理的Linux进程间的通信----->共享内存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 男方不育做试管婴儿吗
- 下一篇: 发奋识天下字的下一句是什么啊?