簡體   English   中英

在父子之間發送消息 - 為什么沒有死鎖?

[英]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!

我正在試圖理解管道,對我來說很少有事情不清楚:

  1. 如果兒子在那行發送他的消息write(fd[1], string, (strlen(string)+1)); 然后我們有printf驗證消息是否已發送,為什么我在收到兒子的消息得到驗證(例如Verification : Message was sent successfully by the SON! )? 是不是它首先是兒子的驗證 ,然后是字符串?

  2. 如果父親試圖從管道中讀取並且兒子想要寫入管道,那么這里的某處隱藏(我認為)死鎖,不是嗎? 為什么我沒有陷入僵局?

謝謝

你的第一個問題:

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都是相關的。 相關= 兩者都必須發生,否則就會出現死鎖 以下情況會導致死鎖。

  1. 孩子沒有執行C1,但做了其他事情,比如等待輸入等但沒有返回,那么父母將在F1中死鎖。
  2. 父母沒有執行F1,但做了其他事情,比如等待輸入等並且沒有返回,那么孩子將被死鎖在C1中。

如果子/父退出,那么你會得到一個破管/ sig-pipe。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM