首頁 > 系統教程 > Linux > Linux進程間如何共享記憶體

Linux進程間如何共享記憶體

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
發布: 2024-06-02 09:18:08
原創
790 人瀏覽過
共享記憶體 IPC 原理

共享記憶體進程間通訊機制主要用於實現進程間大量的資料傳輸,下圖所示為進程間使用共享記憶體實現大量資料傳輸的示意圖:

Linux進程間如何共享記憶體

#共享記憶體是記憶體中單獨開啟的一段記憶體空間,這段記憶體空間有自己獨特的資料結構,包括存取權、大小和最近存取的時間等。此資料結構定義如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

from /usr/include/linux/shm.h

 

struct shmid_ds {

struct ipc_perm shm_perm; /* operation perms 操作权限 */

int shm_segsz; /* size of segment (bytes) 段长度大小 */

__kernel_time_t shm_atime; /* last attach time 最近attach时间 */

__kernel_time_t shm_dtime; /* last detach time 最近detach时间 */

__kernel_time_t shm_ctime; /* last change time 最近change时间 */

__kernel_ipc_pid_t shm_cpid; /* pid of creator 创建者pid */

__kernel_ipc_pid_t shm_lpid; /* pid of last operator 最近操作pid */

unsigned short shm_nattch; /* no. of current attaches */

unsigned short shm_unused; /* compatibility */

void *shm_unused2; /* ditto - used by DIPC */

void *shm_unused3; /* unused */

};

登入後複製

兩個進程在使用此共享記憶體空間之前,需要在進程位址空間與共享記憶體空間之間建立聯繫,即將共享記憶體空間掛載到進程中。

系統對共享記憶體做了以下限制:

1

2

3

4

5

#define SHMMAX 0x2000000 /* max shared seg size (bytes) 最大共享段大小 */

#define SHMMIN 1 /* min shared seg size (bytes) 最小共享段大小 */

#define SHMMNI 4096 /* max num of segs system wide */

#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))

#define SHMSEG SHMMNI /* max shared segs per process */

登入後複製
Linux 共享記憶體管理
1.建立共享記憶體
#

1

#include <sys> #include <sys></sys></sys>

登入後複製
登入後複製

/*
* 第一個參數為 key 值,一般由 ftok() 函數產生
* 第二個參數為想要建立的共享記憶體段大小(單位為位元組)
* 第三個參數用來標識共享記憶體段的建立標識
*/

1

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

登入後複製
2.共享記憶體控制
#

1

#include <sys> #include <sys></sys></sys>

登入後複製
登入後複製

/*
* 第一個參數為要操作的共享記憶體標識符
* 第二個參數為要執行的操作
* 第三個參數為 shmid_ds 結構的暫時共享記憶體變數資訊
*/

1

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

登入後複製
3.映射共享記憶體物件

#系統呼叫 shmat() 函數實作將一個共享記憶體段映射到呼叫程序的資料段中,並傳回記憶體空間首位址,其函數宣告如下:

1

2

3

#include <sys>

#include <sys>

</sys></sys>

登入後複製
登入後複製

/*
* 第一個參數為要操作的共享記憶體標識符
* 第二個參數用來指定共享記憶體的映射位址,非0則為此參數,為0的話由系統分配
* 第三個參數用來指定共享記憶體段的存取權限和映射條件
*/

1

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

登入後複製
4.分離共享記憶體物件

#在使用完畢共享記憶體空間後,需要使用 shmdt() 函數呼叫將其與目前進程分開。函數宣告如下:

1

2

3

#include <sys>

#include <sys>

</sys></sys>

登入後複製
登入後複製

/*
* 參數為分配的共享記憶體首位址
*/

1

int shmdt(const void *shmaddr);

登入後複製
共享內存在父子進程間遵循的約定

#1.使用 fork() 函數建立子程序後,該程序繼承父親程序掛載的共享記憶體。

2.如果呼叫 exec() 執行一個新的程序,則所有掛載的共享記憶體將被自動卸載。

3.如果在某個進程中呼叫了 exit() 函數,所有掛載的共享記憶體將與目前進程脫離關係。

程式實例

申請一段共享內存,父進程在首地址存入一整數,子進程讀出。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#include

#include <sys>

#include <sys>

#include <sys>

#include

#include

 

#define SHM_SIZE 1024

 

int main()

{

int shm_id, pid;

int *ptr = NULL;

</sys></sys></sys>

登入後複製

/* 申請共享記憶體 */

1

shm_id = shmget((key_t)1004, SHM_SIZE, IPC_CREAT | 0600);

登入後複製

/* 映射共享記憶體到進程位址空間 */

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

ptr = (int*)shmat(shm_id, 0, 0);

 

printf("Attach addr is %p \n", ptr);

 

*ptr = 1004;

 

printf("The Value of Parent is : %d \n", *ptr);

 

if((pid=fork()) == -1){

perror("fork Err");

exit(0);

}

else if(!pid){

printf("The Value of Child is : %d \n", *ptr);

exit(0);

}else{

sleep(1);

登入後複製

/* 解除對映 */

1

shmdt(ptr);

登入後複製

/* 刪除共享記憶體 */

1

2

3

4

5

shmctl(shm_id, IPC_RMID, 0);

}

 

return 0;

}

登入後複製

輸出結果:

Linux進程間如何共享記憶體

#

以上是Linux進程間如何共享記憶體的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
centos7 - git的linux版本沒有centos的?
來自於 1970-01-01 08:00:00
0
0
0
學習Linux的先行知識
來自於 1970-01-01 08:00:00
0
0
0
Linux下連接資料庫
來自於 1970-01-01 08:00:00
0
0
0
Linux 批次修改檔名
來自於 1970-01-01 08:00:00
0
0
0
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板