鋼筋混凝土的UNIXC編程技巧_第1頁
鋼筋混凝土的UNIXC編程技巧_第2頁
鋼筋混凝土的UNIXC編程技巧_第3頁
鋼筋混凝土的UNIXC編程技巧_第4頁
鋼筋混凝土的UNIXC編程技巧_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、鋼筋混凝土的 UNIX C 編程技巧(一、內(nèi)存映射表) 前言: 大學畢業(yè)后從事 unix 上的銀行綜合業(yè)務(wù)系統(tǒng)開發(fā)工作已有一年半的時間,向眾多前輩高手 學習了很多經(jīng)驗和技巧,自己也創(chuàng)新了些好的開發(fā)技術(shù),特寫出來與奮斗在一線的 unix 程 序員們共享。本人大學時專注于 windows 平臺應(yīng)用開發(fā),工作后才轉(zhuǎn)入 unix 平臺,故沿 襲了不少 windows 編碼風格。 正文: 在一個帶有數(shù)據(jù)庫的 unix 系統(tǒng)中進行 E-SQL 嵌入式開發(fā), 必然用到很多混合式編程方式。 當系統(tǒng)對表的 SELECT 操作頻繁時,會使數(shù)據(jù)庫效率大幅下降。于是我們很當然的這樣設(shè) 計:當應(yīng)用開始運行時把數(shù)據(jù)庫中需

2、要頻繁查詢的表裝載入共享內(nèi)存, 通過編寫一批共享內(nèi) 存查詢函數(shù)實現(xiàn)對表數(shù)據(jù)的快速查詢、 定位。 這里借用 windows 的一些名詞把這一技術(shù)命 名為 “內(nèi)存映射表 ”技術(shù)。 內(nèi)存映射表的格式設(shè)計有很多方式, 下面介紹一下我設(shè)計的一種格式, 該格式已經(jīng)應(yīng)用于某 省級銀行信用卡全省大前置系統(tǒng),取得非常好的效果。 | | | | | | 內(nèi)存映射表記錄條數(shù) | 第一條記錄結(jié)構(gòu)單元 | 第二條記錄結(jié)構(gòu)單元 | 10 個字節(jié) | 記錄結(jié)構(gòu)的大小 | 記錄結(jié)構(gòu)的大小 | | | | | | 共享內(nèi)存數(shù)據(jù)存放格式如上圖所示。 開頭的 10 個字節(jié)存放內(nèi)存映射表的記錄條數(shù)數(shù)值, 于標準 c 的有符號長整數(shù)類

3、型最大值約為 21 億,所以預(yù)留 10 個字節(jié)存放 ASCII 編碼的記 錄條數(shù)數(shù)值已綽綽有余且取得最大限度值了。 第 11 個字節(jié)開始存放數(shù)據(jù)庫表第一條記錄對 應(yīng)的 c 語言結(jié)構(gòu)體,稱為一個結(jié)構(gòu)單元。后面依次存放所有數(shù)據(jù)庫表記錄形成結(jié)構(gòu)體數(shù)組。 一張數(shù)據(jù)庫表裝載入一塊共享內(nèi)存,可以通過表名給共享內(nèi)存的 ipckey 取名。比如 “公共 系統(tǒng)參數(shù)表 ”對應(yīng)的內(nèi)存映射表的 ipckey 在頭文件里這樣添加 #define SHMY_KEY_GGXTCS 0 x00001138 /* 4408 */,以便于在程序里引用。 內(nèi)存映射表共占用共享內(nèi)存大小為該表記錄對應(yīng)的數(shù)據(jù)結(jié)構(gòu)體大小乘以記錄條數(shù)加上

4、10 個 字節(jié)。比如 “公共系統(tǒng)參數(shù)表 ”記錄條數(shù)為 10 條,表定義如下。那么總占用共享內(nèi)存大小 =(20+30+40)*10+10=910 個字節(jié)。 字段名 字段屬性 長度 空值標志 備注 包括中文注釋和取值范圍 csxh char 20 N.N 參數(shù)序號 csz char 30 N.N 參數(shù)值 cssm char 40 參數(shù)說明 索引 1 unique csxh 內(nèi)存映射表的操作大致有裝載和查詢兩種操作, 其它還可以有簡單的更新操作。 考慮到每個 內(nèi)存映射表的操作大致一樣以及以某個關(guān)鍵字段查詢、更新操作的相似性,再以 “公共系統(tǒng) 參數(shù)表 ”我這樣設(shè)計內(nèi)存映射表的操作函數(shù)原形: int L

5、oadMapGGXTCS(); int FetchMapGGXTCS ( void *pvCondValue , struct REPLACE_STRUCT_TYPE *pREPLACE_STRUCT_ARG , int (* REPLACE_FUNCNAME_COMPARE_PROC) ( void *pvCondValue , struct REPLACE_STRUCT_TYPE *pREPLACE_STRUCT_ARG ) ); int UpdateMapGGXTCS ( void *pvCondValue , void *pvUpdateValue , int (* REPLACE_F

6、UNCNAME_UPDATE_PROC) ( void *pvCondValue , void *pvUpdateValue , struct REPLACE_STRUCT_TYPE *pREPLACE_STRUCT_ARG ) ); 兩個函數(shù)內(nèi)所有涉及到具體表名、 結(jié)構(gòu)體名、 回調(diào)函數(shù)名我都已宏的方式替換掉, 這樣做的 好處是可以形成代碼模板, 如果以后要添加一張表的映射只要復(fù)制代碼模板到實現(xiàn)文件的最 后面,把代碼模板最前面的宏定義成具體的值。 代碼模板最后面把所有用過的宏都反定義掉, 不妨礙后面的程序使用。 裝載表函數(shù)我不用多說了,即把表數(shù)據(jù)裝載入共享內(nèi)存,不需要參數(shù)。 查詢函數(shù)第一個參數(shù)

7、為關(guān)鍵字段值,與 REPLACE_FUNCNAME_COMPARE_PROC 回調(diào) 函數(shù)配合使用。 參數(shù)類型為 void* 類型, 這樣就可以兼容所有類型的數(shù)據(jù)甚至是結(jié)構(gòu)體、 共 用體,額外麻煩的只是把變量傳入前強制傳換成 void* ,在回調(diào)函數(shù)里再轉(zhuǎn)換回具體的變量 第三個 類型。 第二個參數(shù)是結(jié)構(gòu)體宏, 用于函數(shù)成功返回時把符合要求的記錄結(jié)構(gòu)體返回。 參數(shù)是指向回調(diào)函數(shù)的指針, 其作用是針對某一關(guān)鍵字段, 分別取出共享內(nèi)存里的每條記錄 進行比較,當條件符合時,回調(diào)函數(shù)返回0 ,否則返回 1 ,這樣可以不改變外層遍歷函數(shù)的 條件下,使用不同判斷方式、不同的判斷值對內(nèi)存映射表中所有記錄進行遍歷

8、。 本文最后附件中附有裝載、 查詢和更新三個內(nèi)存映射表的代碼模板, 由于完全采用參數(shù)化宏 替換方式設(shè)計,甚至可以不加修改的立即應(yīng)用到您的系統(tǒng)中去。 下面跳躍的介紹一下查詢函數(shù)極其回調(diào)函數(shù)的操作原理。 更新函數(shù)原理與之相似, 結(jié)構(gòu)稍稍 復(fù)雜一些,重點是回調(diào)函數(shù)。 查詢函數(shù) 遍歷內(nèi)存映射表中所有結(jié)構(gòu)記錄 調(diào)用遍歷函數(shù)最后一個參數(shù)即回調(diào)函數(shù)指針(條件值 ,當前結(jié)構(gòu)記錄 ); 如果回調(diào)函數(shù)返回 0 ,即條件符合且更新成功 復(fù)制內(nèi)存映射表中當前結(jié)構(gòu)記錄內(nèi)容到 pREPLACE_STRUCT_ARG 指針空間里,輸出給 用戶 跳出遍歷 ; 偏移到內(nèi)存映射表中下一條結(jié)構(gòu)記錄 ; 返回回調(diào)函數(shù)的返回值 查詢回

9、調(diào)函數(shù) ( 條件值 ,內(nèi)存映射表中當前結(jié)構(gòu)記錄 ) 把便利函數(shù)傳入的條件值強制轉(zhuǎn)換成 char* 類型 ; 與內(nèi)存映射表中當前結(jié)構(gòu)記錄的 csxh 進行比較,如果相等即找到 返回 0; 否則 返回 1; 查詢函數(shù)的使用示例 /* 獲取 對帳場次 */ iRt = FetchMapGGXTCS( (void *)dzcc , if( iRt != 0 ) printf( 獲取對帳場次 失敗 ); else printf( 當前對帳場次為 %s , stGgxtcs.csz ); 運行時數(shù)據(jù)內(nèi)容 使用該設(shè)計通過創(chuàng)建與數(shù)據(jù)庫表映射的共享內(nèi)存數(shù)據(jù)提高對數(shù)據(jù)庫靜態(tài)表 不改變或者只做少量更新的表) 的查詢

10、訪問速度, 而不需要額外占用數(shù)據(jù)庫寶貴的效率, 尤 其在一個對數(shù)據(jù)庫操作頻繁的系統(tǒng)中能很大程度的提高整個系統(tǒng)的運行效率。 本設(shè)計也有不 足之處,主要是只能代替數(shù)據(jù)庫簡單的 SELECT 操作和 UPDATE 操作,不支持 INSERT 、 DELETE操作,不過對于一些靜態(tài)表的查詢使用已經(jīng)足夠了,不是嗎A_A 附件一、內(nèi)存映射表 代碼模塊(以 “公共系統(tǒng)參數(shù)表 ”為例) /* * 獲取 公共系統(tǒng)參數(shù)表 內(nèi)存映射表 相應(yīng)記錄 * */ #define REPLACE_STRUCT_TYPE ggxtcs #define REPLACE_STRUCT_ARG stGgxtcs #define RE

11、PLACE_SHEKEY SHMY_KEY_GGXTCS #define REPLACE_TABLENAME ggxtcs #define REPLACE_TABLEDESC 公共系統(tǒng)參數(shù)表 #define REPLACE_CURSORNAME curGGXTCS #define REPLACE_DBVAR R_GGXTCS #define REPLACE_DBVARFUNC pubVtoSGgxtcs #define REPLACE_FUNCNAME_FETCH FetchMapGGXTCS #define REPLACE_FUNCNAME_LOAD LoadMapGGXTCS #defin

12、e REPLACE_FUNCNAME_COMPARE_PROC CompareKeyFromGGXTCSProc #define REPLACE_FUNCNAME_UPDATE_PROC UpdateValueFromGGXTCSProc int FetchMapGGXTCS ( void *pvCondValue , struct REPLACE_STRUCT_TYPE *pREPLACE_STRUCT_ARG , int (* REPLACE_FUNCNAME_COMPARE_PROC) ( void *pvCondValue , struct REPLACE_STRUCT_TYPE *p

13、REPLACE_STRUCT_ARG ) ); int iReturnValue; struct REPLACE_STRUCT_TYPE *pmpREPLACE_STRUCT_ARG; char *pmp; char acRecordAmount11; long lRecordAmount; long l; _IPC_ID_T ipcid; /* 判斷 內(nèi)存映射表 是否存在 */ iReturnValue = IPCIsShareMemoryExist( REPLACE_SHEKEY ); if( iReturnValue = IPC_SHAREMEMORY_RETURN_ISNT_EXIST

14、 ) /* 若不存在 則創(chuàng)建之 */ iReturnValue = LoadMapGGXTCS(); if( iReturnValue != 0 ) WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_FETCH | LOG_LINELEN |創(chuàng)建 內(nèi)存映射表 REPLACE_TABLEDESC 失敗 錯誤碼 %d errno%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, iReturnValue, errno ); r

15、eturn -1; /* 打開 內(nèi)存映射表 */ ipcid = IPCOpenShareMemory( REPLACE_SHEKEY ); if( ipcid 0 ) WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_FETCH | LOG_LINELEN |打開 內(nèi)存映射表 REPLACE_TABLEDESC 失敗 errno%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, errno ); return -2; /

16、* 連接 內(nèi)存映射表 地址 */ pmp = IPCAttachShareMemory( ipcid ); if( pmp = NULL ) /* 連接失敗,寫出錯日志,函數(shù)返回 */ WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_FETCH | LOG_LINELEN |連接 內(nèi)存映射表 REPLACE_TABLEDESC 失敗 errno%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, errno ); retu

17、rn -3; memset( acRecordAmount , 0 x00 , sizeof( acRecordAmount ) ); strncpy( acRecordAmount , pmp , 10 ); lRecordAmount = atol( acRecordAmount ); pmpREPLACE_STRUCT_ARG = (struct REPLACE_STRUCT_TYPE *)( pmp + 10 ) ; /* 搜尋 內(nèi)存映射表 */ for( l=0 ; llRecordAmount ; l+ ) /* 調(diào)用搜尋回調(diào)函數(shù) */ iReturnValue = REPLACE

18、_FUNCNAME_COMPARE_PROC( pvCondValue , pmpREPLACE_STRUCT_ARG ) ; if( iReturnValue != 1 ) memset( pREPLACE_STRUCT_ARG , 0 x00 , sizeof( struct REPLACE_STRUCT_TYPE ) ); memcpy( pREPLACE_STRUCT_ARG , pmpREPLACE_STRUCT_ARG , sizeof(struct REPLACE_STRUCT_TYPE) ); break; pmpREPLACE_STRUCT_ARG + ; /* 斷開 內(nèi)存映

19、射表 地址連接 */ IPCDetachShareMemory( pmp ); return iReturnValue; /* * 更新 公共系統(tǒng)參數(shù)表 內(nèi)存映射表 * */ int UpdateMapGGXTCS ( void *pvCondValue , void *pvUpdateValue , int (* REPLACE_FUNCNAME_UPDATE_PROC) ( void *pvCondValue , void *pvUpdateValue , struct REPLACE_STRUCT_TYPE *pREPLACE_STRUCT_ARG ) ); int iReturnVal

20、ue; struct REPLACE_STRUCT_TYPE *pmpREPLACE_STRUCT_ARG; char *pmp; char acRecordAmount11; long lRecordAmount; long l; _IPC_ID_T ipcid; /* 判斷 內(nèi)存映射表 是否存在 */ iReturnValue = IPCIsShareMemoryExist( REPLACE_SHEKEY ); if( iReturnValue = IPC_SHAREMEMORY_RETURN_ISNT_EXIST ) /* 若不存在 則創(chuàng)建之 */ iReturnValue = Load

21、MapGGXTCS(); if( iReturnValue != 0 ) WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_FETCH | LOG_LINELEN |創(chuàng)建 內(nèi)存映射表 REPLACE_TABLEDESC 失敗 錯誤碼 %d errno%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, errno ); return -1; /* 打開 內(nèi)存映射表 */ ipcid = IPCOpenShareMemory(

22、 REPLACE_SHEKEY ); if( ipcid 0 ) /* 打開失敗,寫出錯日志,函數(shù)返回 */ WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_FETCH | LOG_LINELEN |打開 內(nèi)存映射表 REPLACE_TABLEDESC 失敗 errno%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, errno ); return -2; /* 連接 內(nèi)存映射表 地址 */ pmp = IPCAtta

23、chShareMemory( ipcid ); if( pmp = NULL ) /* 連接失敗,寫出錯日志,函數(shù)返回*/ WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_FETCH | LOG_LINELEN |連接 內(nèi)存映射表 REPLACE_TABLEDESC 失敗 errno%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, errno ); return -3; memset( acRecordAmount ,

24、 0 x00 , sizeof( acRecordAmount ) ); strncpy( acRecordAmount , pmp , 10 ); lRecordAmount = atol( acRecordAmount ); pmpREPLACE_STRUCT_ARG = (struct REPLACE_STRUCT_TYPE *)( pmp + 10 ) ; /* 搜尋 內(nèi)存映射表 */ for( l=0 ; llRecordAmount ; l+ ) /* 調(diào)用搜尋回調(diào)函數(shù) */ pvUpdateValue , pmpREPLACE_STRUCT_ARG ) ; iReturnValu

25、e = REPLACE_FUNCNAME_UPDATE_PROC( pvCondValue , if( iReturnValue != 1 ) break; pmpREPLACE_STRUCT_ARG + ; /* 斷開 內(nèi)存映射表 地址連接 */ IPCDetachShareMemory( pmp ); return iReturnValue; /* * 裝載 公共系統(tǒng)參數(shù)表 內(nèi)存映射表 * */ int LoadMapGGXTCS() int iReturnValue; struct REPLACE_STRUCT_TYPE REPLACE_STRUCT_ARG; struct REPLAC

26、E_STRUCT_TYPE *pmpREPLACE_STRUCT_ARG; char *pmp; IPC_ID_T ipcid; long lMapSize; memset( /* 獲取表記錄總條數(shù) */ EXEC SQL SELECT count(*) INTO :dlRecordAmount FROM REPLACE_TABLENAME ; if( sqlca.sqlcode ) WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_LOAD | LOG_LINELEN | 獲取 REPLACE_TABLEDESC 總記錄數(shù) 失敗 sqlcode%

27、dn, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, sqlca.sqlcode ); return -1; /* 計算內(nèi)存映射表大小 */ /* 前十個字節(jié)為儲存頭,存放儲存單元的個數(shù) */ lMapSize = dlRecordAmount * sizeof( structREPLACE_STRUCT_TYPE ) + 10 ; /* 創(chuàng)建 內(nèi)存映射表 */ ipcid = IPCCreateShareMemory( REPLACE_SHEKEY , lMapSize ); if(

28、ipcid 0 ) if( errno = EEXIST ) return 0; WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_LOAD | LOG_LINELEN |創(chuàng)建 內(nèi)存映射表 REPLACE_TABLEDESC 失敗 errno%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, errno ); return -2; /* 定義游標 */ EXEC SQL DECLARE REPLACE_CURSORNAME

29、 CURSOR FOR SELECT * FROM REPLACE_TABLENAME ; /* 打開游標 */ EXEC SQL OPEN REPLACE_CURSORNAME ; /* 打開游標 失敗 */ if( sqlca.sqlcode ) WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_LOAD | LOG_LINELEN | 打開 游標 REPLACE_TABLEDESC 失敗 sqlcode%dn, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S

30、), _LINE_, sqlca.sqlcode ); return -3; /* 連接 內(nèi)存映射表 地址 */ pmp = IPCAttachShareMemory( ipcid ); if( pmp = NULL ) /* 連接失敗,寫出錯日志,函數(shù)返回 */ WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_LOAD | LOG_LINELEN | 連接 內(nèi)存映射表 REPLACE_TABLEDESC 失敗 errno%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y

31、-%m-%d %H:%M:%S ), _LINE_, errno ); return -4; sprintf( pmp , %-010d , dlRecordAmount ); pmpREPLACE_STRUCT_ARG = (struct REPLACE_STRUCT_TYPE *)( pmp + 10 ) ; while(1) /* 獲取游標 */ EXEC SQL FETCH REPLACE_CURSORNAME INTO REPLACE_DBVAR; /* 如果記錄已取完,跳出循環(huán) */ if( sqlca.sqlcode = 100 ) break; /* 獲取游標 失敗 */ if

32、( sqlca.sqlcode != 0 ) WriteLog( gacLogFilename, %s | REPLACE_FUNCNAME_LOAD | LOG_LINELEN | 獲取游標 REPLACE_TABLEDESC 失敗 sqlcode%d ,請重啟應(yīng)用 n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, sqlca.sqlcode ); /* 斷開 內(nèi)存映射表 地址連接 */ IPCDetachShareMemory( pmp ); /* 關(guān)閉游標 */ EXEC SQL

33、 CLOSE REPLACE_CURSORNAME; return -5; REPLACE_DBVARFUNC( memcpy( pmpREPLACE_STRUCT_ARG , pmpREPLACE_STRUCT_ARG + ; /* 斷開 內(nèi)存映射表 地址連接 */ IPCDetachShareMemory( pmp ); /* 關(guān)閉游標 */ EXEC SQL CLOSE REPLACE_CURSORNAME; WriteLog( gacLogFilename, 內(nèi)存映 %s | REPLACE_FUNCNAME_LOAD | LOG_LINELEN | %ld 條記錄進入 射表 REPL

34、ACE_TABLEDESC n, GetLocalTimeString( gacTimeStringBuffer , 256 , %Y-%m-%d %H:%M:%S ), _LINE_, dlRecordAmount ); return 0; #undef REPLACE_STRUCT_TYPE #undef REPLACE_STRUCT_ARG #undef REPLACE_SHEKEY #undef REPLACE_TABLENAME #undef REPLACE_TABLEDESC #undef REPLACE_CURSORNAME #undef REPLACE_DBVAR #undef

35、 REPLACE_DBVARFUNC #undef REPLACE_FUNCNAME_FETCH #undef REPLACE_FUNCNAME_LOAD #undef REPLACE_FUNCNAME_COMPARE_PROC #undef REPLACE_FUNCNAME_UPDATE_PROC 附件二、 下面這些函數(shù)被上面的程序調(diào)用過,代碼存放在本人設(shè)計的iIPC 、iLibX 基礎(chǔ)函數(shù) 庫中。 /* * 函數(shù)名 : IPCIsShareMemoryExist * 函數(shù)描述 : 判斷共享存儲塊存在 * 輸入?yún)?shù)說明 : _IPC_ID_T ipckey 共享存儲塊的 id * 返回值 :

36、 存在 返回 IPC_SHAREMEMORY_RETURN_EXIST * 不存在 返回 IPC_SHAREMEMORY_RETURN_ISNT_EXIST */ int IPCIsShareMemoryExist( _IPC_KEY_T ipckey ) _IPC_ID_T ipcid; ipcid=shmget( ipckey , 1 , IPC_CREAT | IPC_EXCL | _giIPCPermission ); if( ipcid = -1 ) return IPC_SHAREMEMORY_RETURN_EXIST; IPCDestroyShareMemory( ipcid )

37、; return IPC_SHAREMEMORY_RETURN_ISNT_EXIST; /* * 函數(shù)名 : IPCOpenShareMemory * 函數(shù)描述 : 打開共享存儲塊 * 輸入?yún)?shù)說明 : _IPC_KEY_T ipckey 共享存儲塊的 key * 返回值 : 成功,返回 共享存儲塊的 id * 失敗,返回 錯誤代碼 */ _IPC_ID_T IPCOpenShareMemory( _IPC_KEY_T ipckey ) int iReturnValue; _IPC_ID_T ipcid; iReturnValue = IPCIsShareMemoryExist( ipckey

38、 ) ; if( iReturnValue = IPC_SHAREMEMORY_RETURN_ISNT_EXIST ) return IPC_SHAREMEMORY_RETURN_ISNT_EXIST; ipcid = shmget( ipckey , 0 , IPC_CREAT | _giIPCPermission ); if( ipcid = -1 ) return IPC_SHAREMEMORY_ERROR_CANT_OPEN; return ipcid; /* * 函數(shù)名 : IPCAttachShareMemory * 函數(shù)描述 : 連接共享存儲塊首地址 * 輸入?yún)?shù)說明 : _IP

39、C_ID_T ipcid 共享存儲塊的 id * 返回值 : 存在 返回 首地址 * 不存在 返回 NULL */ void *IPCAttachShareMemory( _IPC_ID_T ipcid ) void *pvAttach; pvAttach = shmat( ipcid , NULL , 0 ); if( pvAttach = (void *)-1 ) return NULL; else return pvAttach; /* 函數(shù)名 : IPCDetachShareMemory * 函數(shù)描述 : 斷開共享存儲塊首地址 * 輸入?yún)?shù)說明 : void *pvDetach共享存儲

40、塊連接首地址 * 返回值 : 存在 返回 IPC_SHAREMEMORY_RETURN_SUCCESS * 不存在 返回 IPC_SHAREMEMORY_ERROR_CANT_DETACH */ int IPCDetachShareMemory( void *pvDetach ) int i; i = shmdt( pvDetach ); if( i = -1 ) return IPC_SHAREMEMORY_ERROR_CANT_DETACH; else return IPC_SHAREMEMORY_RETURN_SUCCESS; /* * 函數(shù)名 : WriteLog * 函數(shù)描述 : 正

41、常寫日志函數(shù) * 輸入?yún)?shù)說明 : char *pcLogFileName日志文件名 * char *pcFormatString 日志格式串 * . 日志參數(shù)列表 * 返回值 : 成功,返回 TRUE 失敗,返回 FALSE * 更新日志 : 2003/10/18 創(chuàng)建 */ BOOL WriteLog( char *pcLogFileName, char *pcFormatString, . ) va_list valist; BOOL ret; va_start( valist, pcFormatString ); ret=DoLog(pcLogFileName, LOG_WRITE_APPEND, LOG_MODE_RETURN, pcFormatString, valist ); va_end( valist ); return

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論