iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
Software Development

十年後重讀作業系統恐龍本系列 第 8

ch3圖3.25-客戶—伺服器系統的通信:普通的管道(Ordinary Pipes)

  • 分享至 

  • xImage
  •  

Ordinary Pipes(普通管道)允許兩個行程在標準生產者消費者方式下進行通信;生產者從管道的一端[寫入端 (write-end)]寫入,消費者從另一端[讀取端 (read-end)]讀取。以下是普通管道的幾個關鍵特點(來自AI):

特點

  • 單向通訊:
    普通管道是單向的,這意味著數據只能從一個進程流向另一個進程。通常,一個進程寫入管道,而另一個進程從管道中讀取數據。

  • 匿名性:
    普通管道是匿名的 (anaonymous),這意味著它們不會被命名,並且在創建後只能在父進程和其子進程之間使用。

  • 使用 pipe() 函數:
    在 UNIX 系統上,使用 pipe(int fd[]) 函數來建構一個普通管道。這個函數產生一個可透過檔案描述元 (file descriptor) int fd[] 存取的管道:fd[0] 是管道的讀取端,fd[1] 是寫入端。

  • 內存中的緩衝區:
    管道在內存中維護一個緩衝區,用於存儲從寫入端寫入的數據,直到這些數據被讀取。

  • 阻塞行為:
    如果寫入端的緩衝區已滿,寫入操作會阻塞,直到有空間可用。如果讀取端沒有數據可讀,讀取操作也會阻塞,直到有數據可用。

https://ithelp.ithome.com.tw/upload/images/20240922/20168766EUyT4fbbMw.jpg

unix_pipe.c

/**
 * Example program demonstrating UNIX pipes.
 *
 * Figures 3.25 & 3.26
 *
 * @author Silberschatz, Galvin, and Gagne
 * Operating System Concepts  - Ninth Edition
 * Copyright John Wiley & Sons - 2013
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

#define BUFFER_SIZE 25
#define READ_END	0
#define WRITE_END	1

int main(void)
{
	char write_msg[BUFFER_SIZE] = "Mary says Hi here";
	char read_msg[BUFFER_SIZE];
	pid_t pid;
	int fd[2];

	/* create the pipe */
	if (pipe(fd) == -1) {
		fprintf(stderr,"Pipe failed");
		return 1;
	}

	/* now fork a child process 此時,父行程產生子行程*/
	pid = fork();

	if (pid < 0) {
		fprintf(stderr, "Fork failed");
		return 1;
	}

	if (pid > 0) {  /* parent process */
		/* 都要先關掉沒用的一端 close the unused end of the pipe */
		close(fd[READ_END]);

		/* write to the pipe */
		write(fd[WRITE_END], write_msg, strlen(write_msg)+1); 

		/* close the write end of the pipe */
		close(fd[WRITE_END]);
	}
	else { /* child process */
		/* 都要先關掉沒用的一端 close the unused end of the pipe */
		close(fd[WRITE_END]);

		/* read from the pipe */
		read(fd[READ_END], read_msg, BUFFER_SIZE);
		printf("child read %s\n",read_msg);

		/* close the write end of the pipe */
		close(fd[READ_END]);
	}

	return 0;
}

Terminal
編譯並執行

gcc -o unix_pipe unix_pipe.c
./unix_pipe

結果
https://ithelp.ithome.com.tw/upload/images/20240922/20168766rQef2mwVZS.png
由於父行程 fork 產生子行程,所以父行程會先寫入,子行程才有東西讀。
ps.程式執行完不會自己結束,還要我 ctrl+c 結束程式,有點怪><

參考:
greggagne/OSC9e/ch3/unix_pipe.c


上一篇
ch3圖3.23-客戶—伺服器系統的通信:遠程程序呼叫(RPC)
下一篇
ch3.6.3.2-命名管道(Name Pipes)
系列文
十年後重讀作業系統恐龍本30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言