[英]Sending a message between father & son - why there is no deadlock?
鑒於此代碼:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world! I'm the son and this my message!\n";
char readbuffer[80];
pipe(fd); // piping fd[0] & fd[1]
if((childpid = fork()) == -1) // here we create a SON process
{
perror("fork");
exit(1);
}
if(childpid == 0) // child process
{
/* Child process closes up input side of pipe */
close(fd[0]); // closing the READ end from reading , after that the SON would write into fd[1]
/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
printf("Verification : Message was sent successfully by the SON!\n");
exit(0);
}
else // father process
{
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("I'm the father and I received that string: %s", readbuffer);
}
return(0);
}
輸出是:
I'm the father and I received that string: Hello, world! I'm the son and this my message!
Verification : Message was sent successfully by the SON!
我正在試圖理解管道,對我來說很少有事情不清楚:
如果兒子在那行發送他的消息write(fd[1], string, (strlen(string)+1));
然后我們有printf
驗證消息是否已發送,為什么我在收到兒子的消息后得到驗證(例如Verification : Message was sent successfully by the SON!
)? 是不是它首先是兒子的驗證 ,然后是字符串?
如果父親試圖從管道中讀取並且兒子想要寫入管道,那么這里的某處隱藏(我認為)死鎖,不是嗎? 為什么我沒有陷入僵局?
謝謝
你的第一個問題:
1. wasn't it suppose to be first the verification from the son and only then the string ?
答案:當您運行多個進程時,這些進程的指令執行順序不確定。 這取決於調度程序何時進行調度。 因此,從程序的輸出中,我們可以告訴指令執行順序如下:
CHILD-PROCESS:
寫(fd [1],string,(strlen(string)+1)); 在此指令之后,此過程將被暫停
PARENT-PROCESS:
nbytes = read(fd [0],readbuffer,sizeof(readbuffer));
PARENT-PROCESS:
printf(“我是父親,我收到了那個字符串:%s”,readbuffer);
CHILD-PROCESS:
printf(“驗證:消息由SON成功發送!\\ n”);
這個序列也可以是不同的其他時間。
你的問題:
2. Why am I not getting a deadlock ?
答案:在這種情況下,父進程只是阻塞等待管道上的某些輸入。 但孩子可以寫,它不必等待。 所以沒有死鎖的可能性。
1)來自子進程的消息之后出現的原因是因為寫入管道可以阻塞,直到緩沖區中有足夠的空間(從這里開始 ):
如果進程嘗試寫入完整管道(見下文),則寫入(2)塊,直到從管道讀取足夠的數據以允許寫入完成。
換句話說,子進程等待父進程在write()
調用中讀取消息。
2)如果子進程無法向管道寫入任何內容,那么父進程將阻塞(它不會死鎖)。
由於I / O緩沖,無法保證輸出將按打印順序顯示。
當孩子寫入管道時,內核會將父級更改為運行狀態。 似乎調度程序在子項打印文本之前將父項切換為運行(可能在子項從write
調用返回之前)。
所以行
printf("I'm the father and I received that string: %s", readbuffer);
在行之前執行:
printf("Verification : Message was sent successfully by the SON!\n");
您可以使用strace -f
命令驗證這一點。
if(childpid == 0) // child process
{
write(fd[1], string, (strlen(string)+1)); #C1
printf("Verification : Message was sent successfully by the SON!\n"); #C2
exit(0);
}
else // father process
{
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); #F1
printf("I'm the father and I received that string: %s", readbuffer); F2
}
在上述情況下,我們無法確定C1或F1是否會先出現。 它取決於內核調度,不應該依賴。 但是如果管道處於bock模式, C1和F1都是相關的。 相關= 兩者都必須發生,否則就會出現死鎖 。 以下情況會導致死鎖。
如果子/父退出,那么你會得到一個破管/ sig-pipe。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.