首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Linux 信號量 PV 操作:父子進程共享信號量原理解析

     編輯:程式設計疑難解答

疑問核心

fork 後父子進程擁有獨立地址空間,為何對同一信號量的 PV 操作能相互影響?

原理解析

信號量是內核對象,而非進程私有數據。

  • 調用 semget() 或 sem_open() 創建信號量時,內核在系統維護的信號量表中分配條目,返回系統級標識符(ID 或指針)。
  • 父子進程雖然複製了用戶空間的變量(如保存 ID 的整數),但指向同一內核對象。
  • PV 操作(semop()、sem_wait()/sem_post())是系統調用,直接操作內核中的信號量值,因此對所有持有該標識符的進程可見。

類比

像文件描述符:fork 後父子進程持有相同的 fd 數值,讀寫同一文件偏移量會互相影響。信號量同理,內核保證原子性與共享性。

代碼驗證

// 父進程創建
int semid = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
semctl(semid, 0, SETVAL, 0); // 初始值 0

if (fork() == 0) {
    // 子進程 P 操作
    struct sembuf p = {0, -1, 0};
    semop(semid, &p, 1); // 阻塞,因值為 0
    printf("child got semaphore\n");
} else {
    sleep(1);
    // 父進程 V 操作
    struct sembuf v = {0, 1, 0};
    semop(semid, &v, 1); // 釋放,子進程繼續
    wait(NULL);
}

輸出證明子進程阻塞於 P,父進程 V 後子進程繼續,雙方操作同一內核信號量。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved