日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

c++ fork 进程时 共享内存_c/c++ Linux 进程间通信------共享内存

發布時間:2023/12/10 linux 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ fork 进程时 共享内存_c/c++ Linux 进程间通信------共享内存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 什么是共享內存

共享內存(Shared Memory),指兩個或多個進程共享一個給定的存儲區。進程可以將同一段共享內存連接到它們自己的地址空間中,所有進程都可以訪問共享內存中的地址,就好像它們是由用C語言函數malloc分配的內存一樣。而如果某個進程向共享內存寫入數據,所做的改動將立即影響到可以訪問同一段共享內存的任何其他進程。

個人理解:在物理內存上有一塊空間,不同的進程通過頁表將其映射到自己的虛擬地址空間,返回一個地址,通過這個地址可以訪問到那一塊內存空間,此內存空間為共享內存;

2. 原理

下圖中紅線表示不同進程將自己的地址空間映射到不同物理內存中,各自進行自己的任務,不同進程之間獨立工作

不同進程通過共享內存進行通信:

在物理內存上開辟一塊空間,稱為共享內存

不同進程將這塊共享內存連接到自己的地址空間

不同進程以各自地址空間的虛擬地址通過頁表找到共享內存,通過向共享內存中寫數據和讀數據實現進程間通信

3. 共享內存的特點

以傳送數據為目的

所有進程間通信中速度最快的一種方式(例:進程一向共享內存傳送數據,進程二能夠立馬看見傳送的數據,少了若干次拷貝)

共享內存生命周期隨內核

共享沒有自帶同步或互斥,由用戶來維護共享內存

信號量+共享內存通常結合在一起使用,信號量用來同步對共享內存的訪問

4. 共享內存的操作

共享內存的創建

#include

#include

//如果共享內存不存在,創建共享內存,如果存在就打開共享內存

int shmget(key_t key, size_t size, int shmflg);

//返回值:成功返回共享內存的標識符,失敗返回-1

參數:共享內存的關鍵字key

共享內存的標識符,獲取方法和消息隊列 key的方法一致,也可認為key就是共享內存的名字

參數:共享內存的大小size:

由你自己指定,一般指定為4k的倍數(內存4k為一頁)

參數:共享內存的訪問權限shmflg

共享內存的權限,它與文件的訪問權限一樣

IPC_CREAT:創建新的共享內存。

IPC_EXCL:與IPC_CREAT一同使用,表示如果要創建的共享內存已經存在,則返回錯誤。 IPC_NOWAIT:讀寫共享內存要求無法滿足時,不阻塞

0:如果是打開文件,即文件已存在,寫0

共享內存的查看

命令: ipcs -m

共享內存的掛載

#include

#include

//將共享內存鏈接到進程地址空間

void *shmat(int shmid, const void *shmaddr, int shmflg);

//返回值:失敗返回NULL,成功返回一個指針,為地址空間的虛擬地址,并且連接數加1(nattch)

參數:共享內存的標識符shmid

shmget的返回值

參數:指定連接進程地址空間的地址shmaddr

共享存儲段連接到調用進程的哪個地址上與addr參數以及在flag中是否指定SHM_RND位有關

如果addr為0,則此段連接到由內核選擇的第一個可用地址上。這是推薦的使用方式。

如果addr非0,并且沒有指定SHM_RND,則此段連接到addr所指定的地址上。

如果addr非0,并且指定了SHM_ RND,則此段連接到(shmaddr -(shmaddr % SHMLBA))所表示的地址上。SHM_RND命令的意思是取整。SHMLBA的意思是低邊界地址倍數,它總是2的乘方。該算式是將地址向下取最近1個SHMLBA的倍數。

注:除非只計劃在一種硬件上運行應用程序(這在當今是不大可能的),否則不應指定共享段所連接到的地址。所以一般應指定addr為0,以便由內核選擇地址

參數:共享內存的權限shmflg

shmflg = SHM_RDONLY,表示連接操作作用來只讀共享內存

共享內存的卸載

#include

#include

//將共享內存與當前連接進程脫離

int shmdt(const void* shmaddr)

//返回值:成功返回0,失敗返回-1

//參數:由shmat返回的指針

//注意:將共享內存與進程脫離不等于刪除共享內存

共享內存的控制

#include

#include

//shmctl系統調用對shmid標識的共享內存執行cmd操作

//返回值:成功返回0,失敗返回-1

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

參數:共享內存的表示符shmid

shmget的返回值

參數:將要采取的操作cmd

選項 說明

IPC_STAT 把shmid_ds結構中的數據設置為共享內存的當前關聯值

IPC_SET 在進程有足夠權限的前提下,把共享內存的當前關聯值設置為shmid_ds數 據結構中給出的值

IPC_RMID 刪除共享內存

參數:保存共享內存的模式狀態和訪問權限的數據結構buf

共享內存的一些屬性,填NULL

服務端客戶端實例

comm.h

#ifndef __COMM_H__

#define __COMM_H__

#include

#include

#include

#define PATHNAME "."

#define PROJ_ID 0x6666

int createShm(int size);//創建共享內存

int getShm(int size);//獲取共享內存

int destoryShm(int shmid);//銷毀共享內存

#endif

comm.c

#include "comm.h"

static int commShm(int size,int flags)//創建共享內存

{

key_t key = ftok(PATHNAME,PROJ_ID);

if(key < 0){

perror("ftok");

return -1;

}

int shmid = shmget(key, size, flags);

if(shmid < 0){

perror("shmget");

return -2;

}

return shmid;

}

int createShm(int size)

{

return commShm(size, IPC_CREAT | IPC_EXCL);

}

int getShm(int size)//獲取共享內存

{

return commShm(size, IPC_CREAT);

}

int destoryShm(int shmid)//銷毀共享內存

{

if(shmctl(shmid, IPC_RMID,NULL) < 0){

perror("shmctl");

return -3;

}

}

server.c

#include "comm.h"

int main()

{

int shmid = createShm(4096);//創建共享內存

char* addr = (char*)shmat(shmid,NULL,0);//將共享內存進行掛接

int i=0;

while(i++ < 26){

printf("client:%s

總結

以上是生活随笔為你收集整理的c++ fork 进程时 共享内存_c/c++ Linux 进程间通信------共享内存的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。