程序間通訊(二)

2021-09-05 21:24:06 字數 2192 閱讀 7550

傳遞更多的資料

到目前為止我們所用的機制只是簡單的在乙個fread或是fwrite中傳送或是接收全部的資料。有時我們也許以更小的尺寸傳送資料,或是也許我們並不知道輸出的大小。為了避免宣告乙個大的緩衝區,我們可以使用多個fread或是fwrite呼叫並分別處理這些資料。

下面是乙個程式,popen3.c,由乙個管道中讀取所有的資料。

試驗--由乙個管道讀取大量的資料

在這個程式中,我們由乙個被呼叫的ps -alx程序讀取資料。並沒有辦法預先知道會有多少輸出,所以我們必須由管道中多次讀取。

#include

#include

#include

#include

int main()

pclose(read_fp);

exit(exit_success);

}exit(exit_failure);

}我們得到的輸出結果如下:

$ ./popen3

reading:-

pid tty stat  time command

1 ? s       0:04 init

2 ? sw      0:00 [kflushd]

3 ? sw      0:00 [kpiod]

4 ? sw      0:00 [kswapd]

5 ? sw<     0:00 [mdrecoveryd]

...240 tty2 s     0:02 emacs draft1.txt

reading:-

368 tty1 s     0:00 ./popen3

369 tty1 r     0:00 ps -ax

...工作原理

這個程式以與popen1.c相類似的方法使用"r"引數呼叫popen。但是這一次,程式會繼續由檔案流中讀取資料,直到沒有更多的資料。注意,儘管ps命令的執行需要一些時間,linux會安排程序排程,從而在可能時兩個程式同時執行。如果讀程序,popen3,沒有輸入資料,他會掛起,直到有輸入資料。如果寫程序,ps,產生了更多的可緩衝的資料,他就會掛起,直到讀程序消化掉其中的一些資料。

popen是如何實現的

popen呼叫通過首先呼叫shell,sh,將command字串作為引數傳遞給他來執行我們所請求的程式。這有兩個效果,乙個是好的,而另乙個並不是這樣好。

在linux(同時在所有的類unix系統)中,所有的引數擴充套件都是通過shell來完成的,所以在程式被呼叫之前呼叫shell來分析命令字串會允許在程式啟動之前完成任意的shell擴充套件,例如,確定'*.c'實際指向哪些檔案。這通常是非常有用的,而且這允許使用popen來啟動複雜的shell命令。其他的程序建立函式,例如execl,其呼叫可以更為複雜,因呼叫程序必須執行其自己的shell擴充套件。

使用shell的另乙個效果就是對於每乙個popen呼叫,必須為所請求的程式呼叫乙個shell。從而每乙個popen呼叫就會另外兩個額外程序,這就會使得popen函式就系統資源而言更為昂貴,而且目標命令的呼叫速度更慢。

下面是程式popen4.c,我們可以模擬popen的行為。我們通過cat檔案來計算所有popen例子源程式的行數,然後通過管道輸出給wc -l,後者會計算這些行數。在命令列,等同的命令如下:

$ cat popen*.c | wc -l

實際上,wc -l poen*.c命令輸入更為簡單而且更為高效,但是這個例子是為了演示這些原則。

試驗--popen啟動乙個shell

這個程式實際上使用前面的命令,但是通過popen可以讀取結果:

#include

#include

#include

#include

int main()

pclose(read_fp);

exit(exit_success);

}exit(exit_failure);

}當我們執行這個程式,我們會得到下面的輸出:

reading:-

98工作原理

這個程式證明了被呼叫的shell將popen*.c擴充套件為所有以popen開頭並以.c結束的檔案列表,同時處理管道符號,並將cat的輸入傳遞給wc。我們在乙個popen呼叫中呼叫shell,cat程式以及wc程式,並將結果重定向。呼叫命令的程式只看到最終的結果。

程序間通訊(二)

傳遞更多的資料 到目前為止我們所用的機制只是簡單的在乙個fread或是fwrite中傳送或是接收全部的資料。有時我們也許以更小的尺寸傳送資料,或是也許我們並不知道輸出的大小。為了避免宣告乙個大的緩衝區,我們可以使用多個fread或是fwrite呼叫並分別處理這些資料。下面是乙個程式,popen3.c...

程序間通訊《二》

sysv 共享記憶體。sysv 共享記憶體和posix 共享記憶體類似。主要用到的api有 shmget,shmat,shmctl,shmdt,下面將這些api一一道來。intshmget key t key,size t size,intoflag 返回 成功返回共享記憶體的描述字,出錯時 1 在...

程序間通訊(二)

傳遞更多的資料 到目前為止我們所用的機制只是簡單的在乙個fread或是fwrite中傳送或是接收全部的資料。有時我們也許以更小的尺寸傳送資料,或是也許我們並不知道輸出的大小。為了避免宣告乙個大的緩衝區,我們可以使用多個fread或是fwrite呼叫並分別處理這些資料。下面是乙個程式,popen3.c...