編寫一段程式測試圖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.訊息佇列是...