1. 程式人生 > >每天積累一點點

每天積累一點點

概述

共享記憶體是程序間通訊中最簡單的方式之一。共享記憶體允許兩個或更多程序訪問同一塊記憶體,就如同 malloc() 函式向不同程序返回了指向同一個實體記憶體區域的指標。當一個程序改變了這塊地址中的內容的時候,其它程序都會察覺到這個更改。


共享記憶體的特點:
1)共享記憶體是程序間共享資料的一種最快的方法。

 一個程序向共享的記憶體區域寫入了資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。

2)使用共享記憶體要注意的是多個程序之間對一個給定儲存區訪問的互斥。

若一個程序正在向共享記憶體區寫資料,則在它做完這一步操作前,別的程序不應當去讀、寫這些資料。

常用函式

1)建立共享記憶體

所需標頭檔案:

#include <sys/ipc.h>

#include <sys/shm.h>

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

功能:

建立或開啟一塊共享記憶體區。

引數:

key程序間通訊鍵值,ftok() 的返回值。

size:該共享儲存段的長度(位元組)。

shmflg:標識函式的行為及共享記憶體的許可權,其取值如下:

IPC_CREAT:如果不存在就建立
IPC_EXCL:  如果已經存在則返回失敗
位或許可權位:共享記憶體位或許可權位後可以設定共享記憶體的訪問許可權,格式和 open() 函式的 mode_t 一樣(

open() 的使用請點此連結),但可執行許可權未使用。

返回值:

成功:共享記憶體識別符號。

失敗:-1。

示例程式碼如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <sys/ipc.h>
  7. #include <sys/shm.h>
  8. #define BUFSZ 1024
  9. int main(int argc, char
     *argv[])  
  10. {  
  11.     int shmid;  
  12.     key_t key;  
  13.     key = ftok("./", 2015);   
  14.     if(key == -1)  
  15.     {  
  16.         perror("ftok");  
  17.     }  
  18.     //建立共享記憶體
  19.     shmid = shmget(key, BUFSZ, IPC_CREAT|0666);   
  20.     if(shmid < 0)   
  21.     {   
  22.         perror("shmget");   
  23.         exit(-1);   
  24.     }   
  25.     return 0;  
  26. }  

執行結果如下:


2)共享記憶體對映

所需標頭檔案:

#include <sys/types.h>

#include <sys/shm.h>

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

功能:

將一個共享記憶體段對映到呼叫程序的資料段中。簡單來理解,讓程序和共享記憶體建立一種聯絡,讓程序某個指標指向此共享記憶體。

引數:

shmid:共享記憶體識別符號,shmget() 的返回值。

shmaddr:共享記憶體對映地址(若為 NULL 則由系統自動指定),推薦使用 NULL

shmflg:共享記憶體段的訪問許可權和對映條件( 通常為 0 ),具體取值如下:

0:共享記憶體具有可讀可寫許可權。
SHM_RDONLY:只讀。
SHM_RND:(shmaddr 非空時才有效)

返回值:

成功:共享記憶體段對映地址( 相當於這個指標就指向此共享記憶體 )
失敗:-1

3)解除共享記憶體對映

所需標頭檔案:

#include <sys/types.h>
#include <sys/shm.h>

int shmdt(const void *shmaddr);

功能:

將共享記憶體和當前程序分離( 僅僅是斷開聯絡並不刪除共享記憶體,相當於讓之前的指向此共享記憶體的指標,不再指向)。

引數:

shmaddr:共享記憶體對映地址。

返回值:

成功:0

失敗:-1

4)共享記憶體控制

所需的標頭檔案:

#include <sys/ipc.h>

#include <sys/shm.h>

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

功能:

共享記憶體屬性的控制。

引數:

shmid:共享記憶體識別符號。

cmd:函式功能的控制,其取值如下:

IPC_RMID:刪除。(常用 )
IPC_SET:設定 shmid_ds 引數,相當於把共享記憶體原來的屬性值替換為 buf 裡的屬性值。
IPC_STAT:儲存 shmid_ds 引數,把共享記憶體原來的屬性值備份到 buf 裡。
SHM_LOCK:鎖定共享記憶體段( 超級使用者 )。
SHM_UNLOCK:解鎖共享記憶體段。

SHM_LOCK 用於鎖定記憶體,禁止記憶體交換。並不代表共享記憶體被鎖定後禁止其它程序訪問。其真正的意義是:被鎖定的記憶體不允許被交換到虛擬記憶體中。這樣做的優勢在於讓共享記憶體一直處於記憶體中,從而提高程式效能。

buf:shmid_ds 資料型別的地址(具體型別請點此連結 ),用來存放或修改共享記憶體的屬性。

返回值:

成功:0

失敗:-1

實戰示例

接下來我們做這麼一個例子:建立兩個程序,在 A 程序中建立一個共享記憶體,並向其寫入資料,通過 B 程序從共享記憶體中讀取資料。

寫端程式碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define BUFSZ 512

int main(int argc, char *argv[])
{
	int shmid;
	int ret;
	key_t key;
	char *shmadd;
	
	//建立key值
	key = ftok("../", 2015); 
	if(key == -1)
	{
		perror("ftok");
	}
	
	//建立共享記憶體
	shmid = shmget(key, BUFSZ, IPC_CREAT|0666);	
	if(shmid < 0) 
	{ 
		perror("shmget"); 
		exit(-1); 
	}
	
	//對映
	shmadd = shmat(shmid, NULL, 0);
	if(shmadd < 0)
	{
		perror("shmat");
		_exit(-1);
	}
	
	//拷貝資料至共享記憶體區
	printf("copy data to shared-memory\n");
	bzero(shmadd, BUFSZ); // 共享記憶體清空
	strcpy(shmadd, "how are you, lh\n");
	
	return 0;
}

讀程式碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define BUFSZ 512

int main(int argc, char *argv[])
{
	int shmid;
	int ret;
	key_t key;
	char *shmadd;
	
	//建立key值
	key = ftok("../", 2015); 
	if(key == -1)
	{
		perror("ftok");
	}
	
	system("ipcs -m"); //檢視共享記憶體
	
	//開啟共享記憶體
	shmid = shmget(key, BUFSZ, IPC_CREAT|0666);
	if(shmid < 0) 
	{ 
		perror("shmget"); 
		exit(-1); 
	} 
	
	//對映
	shmadd = shmat(shmid, NULL, 0);
	if(shmadd < 0)
	{
		perror("shmat");
		exit(-1);
	}
	
	//讀共享記憶體區資料
	printf("data = [%s]\n", shmadd);
	
	//分離共享記憶體和當前程序
	ret = shmdt(shmadd);
	if(ret < 0)
	{
		perror("shmdt");
		exit(1);
	}
	else
	{
		printf("deleted shared-memory\n");
	}
	
	//刪除共享記憶體
	shmctl(shmid, IPC_RMID, NULL);
	
	system("ipcs -m"); //檢視共享記憶體
	
	return 0;
}

執行結果:


轉自:

相關推薦

每天積累點點】Humans of New York

“I got divorced when I was sixty-four. We had a good run. We were married for 36 years. We’re not enemies.We just outgrew each other. When the kids

每天積累點點】BottomNavigationView使用教程

一:基本用法 1:在res/menu目錄下定義選單佈局: <?xml version="1.0"encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/andr

每天積累點點】Data Binding Library官方教程翻譯

Data Binding Library This document explains how to use the Data Binding Library to writedeclarative layouts and minimize the glue code necessary to

每天積累點點】將PopupWindow顯示在指定位置

//以想在控制元件tvMl的右下角顯示PopupWindow為例(popupWindow的右上角在tvMl的右下角) View popPhotoView = LayoutInflater.from(this).inflate(R.layout.popup_ml_choos

每天積累點點

概述 共享記憶體是程序間通訊中最簡單的方式之一。共享記憶體允許兩個或更多程序訪問同一塊記憶體,就如同 malloc() 函式向不同程序返回了指向同一個實體記憶體區域的指標。當一個程序改變了這塊地址中的內容的時候,其它程序都會察覺到這個更改。 共享記憶體的特點: 1

Web開發知識點彙總(每天積累點點

定義 Servlet是一個執行在Web伺服器端的Java小程式,Servlet接受和響應來自Web客戶端的請求,使用HTTP進行通訊。 HTTP請求 GET-從指定的資源請求資料 POST-

每天進步點點——Ganglia的Python擴展模塊開發

mar 命令 啟動 time_t 重新 source https code eight 轉載請說明出處:http://blog.csdn.net/cywosp/article/details/39701245 註:本文涉及到的代碼都在centos

每天進步點點-Java Serializable(對象序列化)的理解和總結

height puts 信息 new 網絡 停止 之間 internet clas 往硬盤文件裏寫數據 序列化:序列化是將對象轉換為容易傳輸的格式的過程。例如,可以序列化一個對象,然後使用 HTTP 通過 Internet 在客戶端和服務器之間傳輸該對象。在另一端,反序列

程序員,你要每天進步點點-轉載

事情 說了 相愛 調優 集中 nbsp 中間數據 丟了 試驗 第1個一點點:專註眼下 見過太多心猿意馬的程序員,我不得不把「專註眼下」作為天字第一條。他們往往有各式各樣的小夢想,比如做個小茶農、做個小鵝販、做產品、做銷售、做投資,卻被程序員的高薪或是沒有轉行的魄力「耽誤」了

Python 3爬蟲網易雲(五)——每天進步點點(正則表達式下篇之HTML標簽)

tdd htm python swf sofm pts 正則表達 eal href 51忠酶9euka杖淪28炊http://jz.docin.com/ngaxf40277 嵌擲Ic白冉qgw抑亢84http://jz.docin.com/fejci232 gw2d4永

每天進步點點001

程序 存儲 進步 並且 世紀 src png 一點 每天 進步一點點之:2017-09-20 翻譯:很難確切的說現代計算機是在什麽時候發明的。從20世紀30年代到20世紀40年代,許多類似計算機的機器被發明出來。但是這些機器並不具備當代計算機的所有特性。這些特性是機器是電

每天進步點點006

一點 alt self. logs 每天 eat 計算 二進制 instead 翻譯:EDVAC完成之前,許多其他的機器被研制,吸收了Eckert、Mauchly和Neuman設計的要素。其中一部是電動的延遲存儲自動計算機,或簡稱EDSAC,在英國的劍橋大學研制,在194

每天進步點點016

con err sin logs 其中 使用 into src 負責 翻譯:Remintong Rand,現在叫Sperr-Rand Corporation,它制造了許多第二代UNIVAC計算機。然而IBM仍然占據市場,其中最出名的第二代計算機之一是IBM 1401,它是

每天進步點點020

編寫 這才 bsp then .com image cnblogs ole .cn 翻譯:雖然集成電路在1958年被發明,但是第一臺計算機直到1964年才廣泛使用。在那一年,IBM引進了一臺叫System/360大型計算機系列。這一系列計算機成為了使用最廣泛的第三代機器。

每天進步點點029

而不是 但是 logs 現實 es2017 ble more 自己 cnblogs 翻譯:我們可能已經定義了最近的一代計算機並開啟了無代計算機的新時代。雖然計算機制造商稱呼第五代和第六代計算機,但是這種稱呼更多的是一種市場影響而不是現實表現。 備註:meditate(沈思

每天進步點點030

under es2017 nbsp inno 每天 most working spring ati 翻譯:無代計算機觀念提倡者聲明,雖然技術的革新正快速的一個接一個的到來,但沒有一種革新是,或將是足夠重要作為另一代計算機的特征。 備註:advocate(提倡者、擁護者、主

PHP 每天進步點點 按照固定字段排序

每天 sort turn 進步 public key list ret return public function sortbykey($key,$list,$sort) { $flag = array();

PHP每天進步點點 常用linux命令

sel grant ls -lh 進程id add word ls -l linux命令 一個 日常用的,歡迎拍磚 1.創建目錄:mkdir xxx2.查看nginx安裝目錄:ps -ef|grep nginx3.給文件夾一個權限:chmod 777 xxx4.查看lin

PHP每天進步點點 代碼規範之PSR-2

abs bstr oob class turn 表示 interface 名稱 限制 1.概覽 代碼必須遵循PSR-1基本代碼規範。 代碼必須使用四個空格符進行縮進,而不是一個tab鍵。 每行應該保持在80個字符以內,軟限制必須是120個字符,但一定不能有硬性限制。 每個

每天進步點點--Python】 元組 tuple 詳解

Python 元組 Python的元組與列表類似,不同之處在於元組的元素不能修改。 元組使用小括號,列表使用方括號。 元組建立很簡單,只需要在括號中新增元素,並使用逗號隔開即可 例項: tup1 = ('physics', 'chemistry', 1997, 2000) tup2 =