APUE習題10 6(父子程序同步)

2021-07-25 09:08:12 字數 2294 閱讀 8558

編寫一段程式測試圖10_24中父子程序的同步函式,要求程序建立乙個檔案並向檔案寫乙個整數0,然後程序呼叫fork,接著父子程序交替增加檔案中的計數器值,每次計數器值增加1,列印是哪乙個程序進行來該增加1操作

沒有完全按照題目要求做,直接fork之後01234這樣列印的

先上乙個標準輸出的實現

1、寫到標準輸出的實現

main.c:以下實現是有問題的

問題在於:子程序的資料空間、堆疊空間都會從父程序得到乙個拷貝,而不是共享。在子程序對count進行++操作,並沒有影響到父程序著哦您能夠的count值,即使是全域性變數也不會改變,《apue》8.3節說到,子程序是父程序的副本(子程序獲得父程序資料空間、堆和棧的副本)。父程序和子程序並不共享這些儲存空間部分,父程序和子程序共享正文段。

#include "apue.h"

static int count = 0;

int main(void)

else if (pid == 0)

exit(0);

}else

}exit(0);

}

所以會出現以下結果:

正確的實現為:

#include "apue.h"

static int count = 0;

int main(void)

else if (pid == 0)

exit(0);

}else

}exit(0);

}

結果如下:

2、寫檔案實現

fork

的乙個特性是父程序所有的開啟檔案描述符

(file_struct

)都被複製到子程序中,父子程序的每個相同的開啟描述符共享乙個檔案表項如圖。

這種共享的方式使父、子程序對同乙個檔案使用了同乙個檔案偏移量

。如果父、子程序寫到同乙個檔案描述符,但有沒有任何形式的同步,那麼它們的輸出就會相互混合。在fork

之後處理檔案描述符有兩種常見的情況:

(1)父程序等待子程序完成。在這種情況下,父程序無須對其描述符做任何處理。當子程序終止之後,它曾進行過讀、寫的人乙個共享描述符的檔案偏移量已經執行了相應的更新。

(2)父、子程序各自執行不同的程式段。這種情況下,在

fork

之後,父、子程序各自關閉它們不需使用的檔案描述符,這樣就不會干擾對方使用的檔案描述符。這種方式是網路服務程序中常用的方式。

}附上tellwait.c

#include "apue.h"

static volatile sig_atomic_t sigflag; /* set nonzero by sig handler */

static sigset_t newmask, oldmask, zeromask;

static void

sig_usr(int signo) /* one signal handler for sigusr1 and sigusr2 */

void

tell_wait(void)

void

tell_parent(pid_t pid)

void

wait_parent(void)

void

tell_child(pid_t pid)

void

wait_child(void)

APUE 通過管道同步父子程序

include ourhdir.h include pid t fd1 2 父程序讀,子程序寫 fd2 2 父程序寫,子程序讀 static int fd1 2 fd2 2 tell wait函式是在未建立子程序的時候呼叫的 子程序建立之後,父子程序都有fd1 fd2 void tell wait ...

程序同步(一) 程序同步相關概念

在os中引入程序後,雖然提高了資源的利用率和系統吞吐量,但是由於程序的非同步性將會給系統造成混亂,尤其是他們在爭搶臨界資源時。當多個程序去爭用共享變數 鍊錶時,可能導致資料處理出錯。程序同步的任務就是對多個相關程序在執行次序上進行協調,使得併發執行的程序之間能有效地共享資源和相互合作,從而使程式的執...

Linux程序同步

linux程序同步 概述 程序間通訊 ipc 方法主要有以下幾種 管道 fifo 共享記憶體 訊息佇列 訊號量 1.管道中還有命名管道和非命名管道 即匿名管道 之分,非命名管道 即匿名管道 只能用於父子程序通訊,命名管道可用於非父子程序,命名管道就是fifo,管道是先進先出的通訊方式 2.訊息佇列是...