日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

管道实现父子进程的信息传递(一)【fork函数、pipe函数、write/read操作、wait函数】

發布時間:2023/12/13 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 管道实现父子进程的信息传递(一)【fork函数、pipe函数、write/read操作、wait函数】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 題目描述
  • 代碼實現
  • 關于pipe函數
  • 關于讀寫操作
  • 關于讀寫端口
  • 關于wait函數
    • 功能:
    • 注意:
  • 關于fork函數


題目描述

編寫一個程序,利用管道實現父子進程的通信,父進程向子進程發送信息,由子進程輸出顯示。

代碼實現

#include <stdio.h> #include <stdlib.h> #include <unistd.h> //管道功能所在的頭文件 #include <sys/types.h> //wait函數所在的頭文件 #include <sys/wait.h> //wait函數所在的頭文件#define MAXLINE 80int main() {int n; //所發送消息的長度int fd[2]; //管道讀寫端口pid_t pid; //進程號char line[MAXLINE]; //消息緩沖區if(pipe(fd) < 0) //建立管道不成功{perror("pipe");exit(1); //有錯誤型的退出}if((pid = fork()) < 0) //建立子進程不成功{perror("fork:");exit(1);}else //成功建立子進程{ if(pid > 0) //父進程{close(fd[0]); //關閉讀端write(fd[1],"I love CMY!\n", 12); //把"I love CMY!\n"長度為12的字符送到管道寫端口fd[1]close(fd[1]); //關閉寫端,老師是要求寫完之后要關閉的,但是我試了試不寫也沒啥問題……wait(NULL); //父進程等待子進程結束}else //子進程{close(fd[1]); //關閉寫端n = read(fd[0], line, MAXLINE); //從管道讀端口fd[0]把長度為MAXLINE的字符送到line中write(STDOUT_FILENO, line, n); //將line中長度為n的字符寫到標準輸出設備(即屏幕上)close(fd[0]); //同上,關閉讀端,老師是要求寫完之后要關閉的,但是我試了試不寫也沒啥問題……} }return 0; }

關于pipe函數

功能:創建一個普通管道


關于讀寫操作

也就是說讀/寫操作的流程是:

  • 關閉讀/寫端
  • 進行寫/讀操作
  • 寫/讀完關閉寫/讀端

關于讀寫端口

為什么fd[0]是讀,fd[1]是寫,能不能顛倒過來?

一般來講,我們常說:讀寫讀寫,不說寫讀寫讀,因為不順口。所以0是讀,1是寫,你要是想顛倒也是可以的,只要你自己記得住就行。


關于wait函數


功能:

父進程一旦調用了wait就立即阻塞自己,由wait自動分析是否當前進程的某個子進程已經退出,如果讓它找到了這樣一個已經變成僵尸的子進程,wait就會收集這個子進程的信息,并把它徹底銷毀后返回;如果沒有找到這樣一個子進程,wait就會一直阻塞在這里,直到有一個出現為止。

注意:

當父進程沒有用wait()函數等待已終止的子進程時,子進程就會進入一種無父進程的狀態,此時子進程就是僵尸進程。
如果先終止父進程,子進程依然會繼續正常進行,只是它將由init進程(PID 1)繼承,當子進程終止時,init進程捕獲這個狀態。


關于fork函數

其實本題就是管道和父子進程的相結合,重點是理解fork()之后父子進程的并行執行,以老師PPT中的例題為例:

子進程執行的是 val == 0 的內容,而父進程執行的是 val > 0 的內容,子進程創建的時候完全復制了父進程的資源,可以理解為自 val = fork() 之后,代碼就被copy了一份一摸一樣的,父進程執行被copy的,子進程執行copy的。而對于本題而言,從

if((pid = fork()) < 0) //建立子進程不成功

開始,子進程copy了后面的代碼,而且繼承了父進程之前的資源,如變量等,然后在接下來的代碼中根據pid的不同進入不同的代碼段。

值得注意的是,本題代碼中先處理的是父進程的寫操作,再處理的是子進程的讀操作,那如果反過來先寫子進程的讀操作,再寫父進程的寫操作,代碼還可以正常運行嗎?

經過測試,答案是可以,因為我們剛講過他們倆是并行執行嘛,但是根據先寫進去再讀出來比較符合人類的思維,所以我們本題就先寫父進程的寫操作,再處理子進程的讀操作~

證據如下圖:

總結

以上是生活随笔為你收集整理的管道实现父子进程的信息传递(一)【fork函数、pipe函数、write/read操作、wait函数】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。