|
https://blog.csdn.net/u013485792/article/details/50764224 關(guān)于ftok函數(shù),先不去了解它的作用來先說說為什么要用它,共享內(nèi)存,消息隊(duì)列,信號(hào)量它們?nèi)齻€(gè)都是找一個(gè)中間介質(zhì),來進(jìn)行通信的,這種介質(zhì)多的是。就是怎么區(qū)分出來,就像唯一一個(gè)身份證來區(qū)分人一樣。你隨便來一個(gè)就行,就是因?yàn)檫@。只要唯一就行,就想起來了文件的設(shè)備編號(hào)和節(jié)點(diǎn),它是唯一的,但是直接用它來作識(shí)別好像不太好,不過可以用它來產(chǎn)生一個(gè)號(hào)。ftok()就出場(chǎng)了。ftok函數(shù)具體形式如下: key_t ftok(const char *pathname, int proj_id); 其中參數(shù)fname是指定的文件名,這個(gè)文件必須是存在的而且可以訪問的。id是子序號(hào),它是一個(gè)8bit的整數(shù)。即范圍是0~255。當(dāng)函數(shù)執(zhí)行成功,則會(huì)返回key_t鍵值,否則返回-1。在一般的UNIX中,通常是將文件的索引節(jié)點(diǎn)取出,然后在前面加上子序號(hào)就得到key_t的值。 有關(guān)該函數(shù)的三個(gè)常見問題: 1.pathname是目錄還是文件的具體路徑,是否可以隨便設(shè)置 解答: 1、ftok根據(jù)路徑名,提取文件信息,再根據(jù)這些文件信息及project ID合成key,該路徑可以隨便設(shè)置。 2、該路徑是必須存在的,ftok只是根據(jù)文件inode在系統(tǒng)內(nèi)的唯一性來取一個(gè)數(shù)值,和文件的權(quán)限無關(guān)。 3、proj_id是可以根據(jù)自己的約定,隨意設(shè)置。這個(gè)數(shù)字,有的稱之為project ID; 在UNIX系統(tǒng)上,它的取值是1到255; 簡單驗(yàn)證: 用到的代碼,文件wxyuan.c: 關(guān)于ftok()函數(shù)的一個(gè)陷阱在使用ftok()函數(shù)時(shí),里面有兩個(gè)參數(shù),即fname和id,fname為指定的文件名,而id為子序列號(hào),這個(gè)函數(shù)的返回值就是key,它與指定的文件的索引節(jié)點(diǎn)號(hào)和子序列號(hào)id有關(guān),這樣就會(huì)給我們一個(gè)誤解,即只要文件的路徑,名稱和子序列號(hào)不變,那么得到的key值永遠(yuǎn)就不會(huì)變。 事實(shí)上,這種認(rèn)識(shí)是錯(cuò)誤的,想想一下,假如存在這樣一種情況:在訪問同一共享內(nèi)存的多個(gè)進(jìn)程先后調(diào)用ftok()時(shí)間段中,如果fname指向的文件或者目錄被刪除而且又重新創(chuàng)建,那么文件系統(tǒng)會(huì)賦予這個(gè)同名文件新的i節(jié)點(diǎn)信息,于是這些進(jìn)程調(diào)用的ftok()都能正常返回,但鍵值key卻不一定相同了。由此可能造成的后果是,原本這些進(jìn)程意圖訪問一個(gè)相同的共享內(nèi)存對(duì)象,然而由于它們各自得到的鍵值不同,實(shí)際上進(jìn)程指向的共享內(nèi)存不再一致;如果這些共享內(nèi)存都得到創(chuàng)建,則在整個(gè)應(yīng)用運(yùn)行的過程中表面上不會(huì)報(bào)出任何錯(cuò)誤,然而通過一個(gè)共享內(nèi)存對(duì)象進(jìn)行數(shù)據(jù)傳輸?shù)哪? 的將無法實(shí)現(xiàn)。 這是一個(gè)很重要的問題,希望能謹(jǐn)記!??! 所以要確保key值不變,要么確保ftok()的文件不被刪除,要么不用ftok(),指定一個(gè)固定的key值。 Ubuntu下,ftok()產(chǎn)生鍵值的原理: 執(zhí)行該源碼: satellite@ubuntu:~/test$ ./wxyuan 有關(guān)st_dev和st_ino的定義如下: |
|
|