日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

使用 UNIX System V IPC 機(jī)制共享應(yīng)用程序數(shù)據(jù)( 五 )


關(guān)于信號(hào)量,要注意的最后一個(gè)事項(xiàng)在于,它們被稱(chēng)為建議鎖(Advisory Lock) 。這意味著信號(hào)量本身并不阻止兩個(gè)進(jìn)程同時(shí)使用同一個(gè)資源;相反,它們旨在建議任何進(jìn)程自愿詢(xún)問(wèn)該資源是否正在使用 。
共享內(nèi)存空間
共享內(nèi)存也許是最強(qiáng)大的 SysV IPC 方法,并且此方法最容易實(shí)現(xiàn) 。顧名思義,共享內(nèi)存是在兩個(gè)進(jìn)程之間共享一個(gè)內(nèi)存塊 。清單 7 顯示了一個(gè)程序,該程序調(diào)用 fork(2) 來(lái)將自身劃分為一個(gè)父進(jìn)程和一個(gè)子進(jìn)程,兩個(gè)進(jìn)程之間使用一個(gè)共享內(nèi)存段進(jìn)行通信 。
清單 7. 演示共享內(nèi)存用法的程序
#include
#include
#include
#include
#include
#include
int main(void) {
pid_t pid;
int *shared; /* pointer to the shm */
int shmid;
shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666);
if (fork() == 0) { /* Child */
/* Attach to shared memory and print the pointer */
shared = shmat(shmid, (void *) 0, 0);
printf("Child pointer %pn", shared);
*shared=1;
printf("Child value=https://www.rkxy.com.cn/dnjc/%dn", *shared);
sleep(2);
printf("Child value=https://www.rkxy.com.cn/dnjc/%dn", *shared);
} else { /* Parent */
/* Attach to shared memory and print the pointer */
shared = shmat(shmid, (void *) 0, 0);
printf("Parent pointer %pn", shared);
printf("Parent value=https://www.rkxy.com.cn/dnjc/%dn", *shared);
sleep(1);
*shared=42;
printf("Parent value=https://www.rkxy.com.cn/dnjc/%dn", *shared);
sleep(5);
shmctl(shmid, IPC_RMID, 0);
}
}
您現(xiàn)在應(yīng)該已經(jīng)熟悉傳遞給 shmget 的參數(shù)了:密鑰、大小和標(biāo)志 。此示例中的共享內(nèi)存大小是單個(gè)整數(shù) 。清單 7 與前一個(gè)示例的不同之處在于它對(duì) IPC 密鑰使用了 IPC_PRIVATE 。當(dāng)使用了 IPC_PRIVATE 時(shí),將保證創(chuàng)建一個(gè)唯一的 IPC ID,并且預(yù)期應(yīng)用程序?qū)⒆约悍职l(fā)該 ID 。在此示例中,父進(jìn)程和子進(jìn)程都知道 shmid,因?yàn)樗鼈兎謩e是對(duì)方的副本 。fork 系統(tǒng)調(diào)用創(chuàng)建當(dāng)前進(jìn)程的第二個(gè)副本,稱(chēng)為子進(jìn)程,此進(jìn)程幾乎與父進(jìn)程完全相同 。兩個(gè)進(jìn)程的執(zhí)行都在 fork 之后恢復(fù) 。返回值將用于確定當(dāng)前進(jìn)程是父進(jìn)程還是子進(jìn)程 。
父進(jìn)程和子進(jìn)程看起來(lái)相似 。首先,shmat 系統(tǒng)調(diào)用被用于獲得指向共享內(nèi)存段的指針 。shmat 需要共享內(nèi)存 ID、一個(gè)指針和某些標(biāo)志 。該指針用于請(qǐng)求特定的內(nèi)存地址 。通過(guò)傳遞 0,內(nèi)核可以隨心所欲地選擇任何內(nèi)存地址 。標(biāo)志大部分是特定于供應(yīng)商的,不過(guò) SHM_RDONLY 是一個(gè)公共標(biāo)志,用于指示不寫(xiě)入的段 。如清單 7 所示,shmat 的常見(jiàn)用法是讓內(nèi)核決定一切 。
shmat 返回一個(gè)指向共享內(nèi)存段的指針,此示例出于調(diào)試目的而將其打印到了屏幕上 。然后每個(gè)進(jìn)程依次修改該共享內(nèi)存段,并打印出值 。最后,父進(jìn)程使用 shmctl(2) 來(lái)刪除共享內(nèi)存段 。清單 8 顯示了此程序的輸出 。
清單 8. 共享內(nèi)存示例的輸出
sunbox$ ./shared_memory
Child pointer ff390000
Child value=https://www.rkxy.com.cn/dnjc/1
Parent pointer ff380000
Parent value=https://www.rkxy.com.cn/dnjc/1
Parent value=https://www.rkxy.com.cn/dnjc/42
Child value=https://www.rkxy.com.cn/dnjc/42
您可以從輸出中看到相同內(nèi)存空間的共享 。起初,共享內(nèi)存中的值為 1,這是由子進(jìn)程設(shè)置并由父進(jìn)程讀取的 。然后父進(jìn)程將該值設(shè)置為 42,并由子進(jìn)程讀取 。請(qǐng)注意,父進(jìn)程和子進(jìn)程擁有指向共享內(nèi)存段的不同指針地址,盡管它們是在訪問(wèn)相同的物理內(nèi)存 。在使用物理地址時(shí),這會(huì)導(dǎo)致某些數(shù)據(jù)結(jié)構(gòu)出現(xiàn)問(wèn)題,例如鏈表,因此當(dāng)您在共享內(nèi)存中構(gòu)建復(fù)雜結(jié)構(gòu)時(shí),可以使用相對(duì)尋址 。

推薦閱讀