在Linux下父子程序對共享儲存區的訪問

2021-10-06 20:24:42 字數 4958 閱讀 3672

子程序向共享儲存區寫資料,父程序讀共享儲存區資料。

子程序向共享儲存區修改資料,父程序讀共享儲存區資料

本次實驗其實重點的是這麼幾個變數:addr、shmid 以及幾個重要的函式:shmet、shmat、shmget、shmctl

對於系統v共享記憶體,主要有以下幾個api:shmget()、shmat()、shmdt()及shmctl()。

#include

#include

shmget()用來獲得共享記憶體區域的id,如果不存在指定的共享區域就建立相應的區域。shmat()把共享記憶體區域對映到呼叫程序的位址空間中去,這樣,程序就可以方便地對共享區域進行訪問操作。shmdt()呼叫用來解除程序對共享記憶體區域的對映。shmctl實現對共享記憶體區域的控制操作。

注:shmget的內部實現包含了許多重要的系統v共享記憶體機制;shmat在把共享記憶體區域對映到程序空間時,並不真正改變程序的頁表。當程序第一次訪問記憶體對映區域訪問時,會因為沒有物理頁表的分配而導致乙個缺頁異常,然後核心會根據相應的儲存管理機制為共享記憶體對映區域分配相應的頁表。

應當指出,共享儲存區機制只為程序提供了用於實現通訊的共享儲存區和對共享儲存區進行操作的手段,然而並未提供對該區進行互斥訪問及程序同步的措施。因而當使用者需要使用該機制時,必須自己設定同步和互斥措施才能保證實現正確的通訊。
涉及的系統呼叫

1、shmget( )

建立、獲得乙個共享儲存區。

系統呼叫格式:

shmid=shmget(key,size,flag)
該函式使用標頭檔案如下:

#include

#include

#include

引數定義

int  shmget(key,size,flag);

key_t key;

int size,flag;

其中,key是共享儲存區的名字;size是其大小(以位元組計);flag是使用者設定的標誌,如ipc_creat。ipc_creat表示若系統中尚無指名的共享儲存區,則由核心建立乙個共享儲存區;若系統中已有共享儲存區,便忽略ipc_creat。

控制命令 值

ipc_creat 0001000

ipc_excl 0002000

例:shmid=shmget(key,size,(ipc_creat|0400))

建立乙個關鍵字為key,長度為size的共享儲存區
系統呼叫格式:

virtaddr=shmat(shmid,addr,flag)
該函式使用標頭檔案如下:

#include

#include

#include

引數定義

char  *shmat(shmid,addr,flag);

int shmid,flag;

char * addr;

其中,shmid是共享儲存區的識別符號;addr是使用者給定的,將共享儲存區附接到程序的虛位址空間;flag規定共享儲存區的讀、寫許可權,以及系統是否應對使用者規定的位址做捨入操作。其值為shm_rdonly時,表示只能讀;其值為0時,表示可讀、可寫;其值為shm_rnd(取整)時,表示作業系統在必要時捨去這個位址。該系統呼叫的返回值是共享儲存區所附接到的程序虛位址viraddr。

3、shmdt( )

把乙個共享儲存區從指定程序的虛位址空間斷開。

系統呼叫格式:

shmdt(addr)
該函式使用標頭檔案如下:

#include

#include

#include

引數定義

int  shmdt(addr);

char addr;

4、shmctl( )

共享儲存區的控制,對其狀態資訊進行讀取和修改。

系統呼叫格式:

shmctl(shmid,cmd,buf)
該函式使用標頭檔案如下:

#include

#include

#include

引數定義

int  shmctl(shmid,cmd,buf);

int shmid,cmd;

struct shmid_ds *buf;

其中,buf是使用者緩衝區位址,cmd是操作命令。命令可分為多種型別:

(1)用於查詢有關共享儲存區的情況。如其長度、當前連線的程序數、共享區的建立者識別符號等;

(2)用於設定或改變共享儲存區的屬性。如共享儲存區的許可權、當前連線的程序計數等;

(3)對共享儲存區的加鎖和解鎖命令;

(4)刪除共享儲存區識別符號等。

上述的查詢是將shmid所指示的資料結構中的有關成員,放入所指示的緩衝區中;而設定是用由buf所指示的緩衝區內容來設定由shmid所指示的資料結構中的相應成員。

cmd有下列幾種數值:

ipc_stat 把共享記憶體的

ipc_set 將引數buf所指的shmid_ds 結構中的shm_perm.uid、shm_perm.gid和shm_perm.mode複製到共享記憶體的shmid_ds結構內。

ipc_rmid 刪除共享記憶體和資料結構。

shm_lock 不讓此共享記憶體置換到swap。

shm_unlock 允許此gon共享記憶體置換到swap。

shm_lock 和shm_unlock為lunix特有,且唯有超級使用者(root)允許使用

而我們常用的是刪除共享記憶體即ipc_rmid.

1、fork()是建立程序函式。

2、c程式一開始,就會產生 乙個程序,當這個程序執行到fork()的時候,會建立乙個子程序。

3、此時父程序和子程序是共存的,它們倆會一起向下執行c程式的**。

下面直接做乙個實驗深入理解 ==其實if()裡面的語句都可以刪除,看著也好看,做著也簡潔。

#include

#include

#include

#include

#include

#include

#define bufsz 1024

void

main()

printf

("segment created:%d\n,shmid");

system

("ipcs -m");

shmadr=

shmat

(shmid,0,

0)if(shmadr<

(char*)

0)// 這裡我沒除錯 報錯可以寫if(shmadr<(void*)0)

printf

("segment attached at %p\n"

,shmadr)

;system

("ipcs -m");

for(i =

0;i<

10;i++

) shmadr[i]

=i+48

;// 向共享記憶體區寫入資料

shmadr[i]

='\0'

;//字串if(

(shmdt

(shmadr)

)<0)

put(

"segment detached");

system

("ipcs -m");

if(child=

fork()

==-1)

else

if(child==0)

//子程序

printf

("segment attached at %p"

,shmadr)

;system

("ipcs -m");

printf

("the child process change share memory!\n");

printf

("the old content share memory:%s\n"

,shmadr)

;// 修改共享記憶體區資料

for(i=

0;i<

12;i++

) shmadr[i]

=i+'a'

; shmadr[i]

='\0'

;printf

("the new content of share memory:%s\n"

,shmadr);if

((shmdt

(shmadr)

)<0)

puts

("segment detached");

system

("ipcs -m");

exit

(exit_sucess);}

else

printf

("segment attached at%p\n"

,chmadr)

;system

("ipcs -m");

printf

("the parent process read share memory\n");

printf

("the content of share memory:%s\n"

,shmadr);if

((shmdt

(shmadr)

)<0)

//斷開與共享記憶體的連線

puts

("segment detached");

system

("ipcs -m");

if(shmctl

(shmid,ipc_rmid,

null))

<0)

//刪除共享記憶體區

}```c

linux 對父子程序共享檔案描述符的理解

重新回顧一下什麼是檔案描述符 檔案描述符是由無符號整數表示的控制代碼,程序使用它來標識開啟的檔案。檔案描述符與包括相關資訊 如檔案的開啟模式 檔案的位置型別 檔案的初始型別等 的檔案物件相關聯,這些資訊被稱作檔案的上下文。父子程序共享檔案描述符 相當於2個 fd指向同一塊記憶體空間.因為2個程序共享...

有關Linux下父子程序內容

1 父程序可以利用wait waitpid 等待子程序的結束,避免僵死子程序的產生,當然也可以迴圈的wait watipid 來等待所有的子程序的結束 最好可以用法是,在子程序結束時,會向父程序傳送的sigchld訊號,父程序通過 signal sigaction 來響應子程序的結束.具體例項可參考...

Linux父子程序之間的資料共享分析

全域性變數 棧區 區域性變數 堆區 動態開闢 檔案 不共享 不共享 不共享 共享檔案偏移量1.在fork之前開啟檔案的話,那麼fork之後父子程序的檔案描述符fd相同。2.父子程序檔案描述符是共享的,但是關閉的時候可以分別關閉,也可以同時在公有 中關閉,類似於引用計數,只不過是被不同程序所引用。參考...