自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

在AIX上通過數(shù)據(jù)管道實現(xiàn)進程間通訊

系統(tǒng) 其他OS
在 AIX 應用開發(fā)中會遇到進程間通訊的需求,進程間通訊的方法有很多,例如通過共享內(nèi)存、信號燈、內(nèi)存映射文件、數(shù)據(jù)管道、文件、Socket 等等。這里主要介紹一種通過數(shù)據(jù)管道和系統(tǒng)標準輸入輸出文件描述符相結合的方式來實現(xiàn)進程間通訊和數(shù)據(jù)交互。

 在 AIX 應用開發(fā)中會遇到進程間通訊的需求,進程間通訊的方法有很多,例如通過共享內(nèi)存、信號燈、內(nèi)存映射文件、數(shù)據(jù)管道、文件、Socket 等等。這里主要介紹一種通過數(shù)據(jù)管道和系統(tǒng)標準輸入輸出文件描述符相結合的方式來實現(xiàn)進程間通訊和數(shù)據(jù)交互。本文面向 AIX 或其他 UNIX 平臺 C 語言的開發(fā)者,讀者需要具備一定進程間匿名管道通訊的知識,并且對文件描述符、基本的 I/O 操作有一定了解。

什么是匿名管道

管道是進程間協(xié)同工作的一種方式,單獨構成一種獨立的文件系統(tǒng),管道是半雙工的。而匿名管道數(shù)據(jù)只能向一個方向流動,雙方通信時,需要建立起兩個管道;只能用于父子進程或者兄弟進程之間(具有親緣關系的進程)。

文件指針與管道

當我們要讀寫一個文件,需要用到文件指針,它是一個指向結構體的指針。我們對管道進行讀寫操作時也需要用到文件指針,通過文件指針來對管道一端進行寫,而另一端的進程則通過文件指針進行讀。如果文件指針指向的是標準輸入,那么該進程則是從標準輸入中讀取數(shù)據(jù),本文利用文件指針進行匿名管道的讀寫操作。

通過匿名管道實現(xiàn)進程間通訊

通信場景如下:現(xiàn)在有兩個進程 A、進程 B( 是進程 A 的子進程 ),進程 A 從數(shù)據(jù)庫中讀取一條待處理數(shù)據(jù) M,數(shù)據(jù) M 中存儲了進程 A 需要調(diào)用的可執(zhí)行程序名稱及需要傳遞給可執(zhí)行程序的參數(shù)。由于參數(shù)很多,并且參數(shù)長度及個數(shù)以及類型都是變化的,所以這里不采取參數(shù)傳遞方法,采用了匿名管道進程間通信方法。

匿名管道通信

圖1. 匿名管道通信

 

進程 A 和進程 B 的標準輸出都輸出到指定的日志文件 logfile 中,進程 A 實現(xiàn)通過調(diào)用 popen 會另外 fork 一個進程 B, 而進程 A 和進程 B 之間建立起了一個數(shù)據(jù)管道(這里進程 A 寫入,進程 B 讀出)。這里要做一下說明,進程 B 本身就是 a.out的可執(zhí)行程序,popen 原理是 fork 后再執(zhí)行 exec 家族函數(shù)。我們知道 exec 家族函數(shù)特點就是調(diào)用進程的實體,包括代碼段,數(shù)據(jù)段和堆棧等都已經(jīng)被新的內(nèi)容取代。另外,子進程(進程 B)的標準輸入就是數(shù)據(jù)管道的”讀端”,而管道”寫端”在父進程以文件指針形式存在。這樣父進程(進程 A)可以通過對 popen 返回的文件指針操作進行寫操作,子進程(進程 B)可以通過讀取標準輸入來獲取數(shù)據(jù)管道傳遞過來的數(shù)據(jù)。并且子進程的標準輸出與父進程是相同的,由于調(diào)用 popen 時( FILE * popen( const char * command , const char * type) ),command 參數(shù)執(zhí)行了重定向標準輸出到 logfile,所以在子進程 ( 進程 B) 中調(diào)用任何 printf 標準輸出函數(shù)都會將數(shù)據(jù)寫到 logfile 中去。

清單 1. 進程 A 簡要代碼(fileA.sqc)

fileA.sqc
#include
#include
#include
#include
…
static int npWrite( FILE *fp , const char * tovalue, FILE *fp1 )
{
int iLen = 0, iRetLen = 0;
iLen = strlen( tovalue );
… .
iRetLen = fwrite( tovalue , sizeof( char ) , iLen , fp );
…
return 0;
}
int request()
{
FILE * fp = 0x00;
FILE * fpw =0x00;
char logfile[100];
char batfile[100];
char binpath[100];
char execfile[100];
… ..
(1)
sprintf( execfile , "%s/%s %s %s %s %s 1>>%s",
binpath,”a.out”,“123456”,”2011-01-01”,”test”,“A0001”,logfile);
fpw = 0x00;
(2)
/* 通過 popen 當前進程 ( 進程 A) 會通過 fork 和 exec 系統(tǒng)調(diào)用來啟動一個子進程,( 子進程代
** 碼見 fileB.sqc), 子進程也就是我們前面講述到的進程 B。那么進程 A 是進程 B 的父進程 .
*/
fpw = popen( execfile ,"w");
if ( fpw == 0x00 )
{
fprintf( fp , " popen error %s\n.", strerror( errno ) );
fclose( fp );
return -1;
}
… .
if ( npWrite( fpw , “hello world” , fp ) ) return -1;
… .
pclose( fpw );
fflush( fp );
… .
fclose( fp );
return 0;
}

源文件 fileA.sqc中調(diào)用 popen 函數(shù)來創(chuàng)建匿名管道,該函數(shù)需要注意以下幾點:

1) popen 函數(shù)用創(chuàng)建管道的方式啟動一個進程 ( 進程 B,即調(diào)用 popen 函數(shù)的進程的子進程 ) 并調(diào)用 Shell。管道是單向的,所以只能定義成只讀或者只寫。

2) popen 函數(shù)的返回值是一個普通的標準 I/O 流,它只能用 pclose 而不是 fclose 函數(shù)來關閉。向這個流的寫入被轉(zhuǎn)化為對 command 命令的標準輸入;而 command 命令的標準輸出則和調(diào)用 popen 函數(shù)的進程相同,除非這個被 command 命令自己改變。相反的 , 讀取一個“被 popen 了的”流,就相當于讀取 command 命令的標準輸出,而 command 的標準輸入則是和調(diào)用 popen 函數(shù)的進程相同。

3) popen 函數(shù)的輸出流默認是被全緩沖的,poepn 函數(shù)等待相關的進程結束并返回一個 command 命令的退出狀態(tài) , 就像 wait4 函數(shù) 一樣。

在 fileA.sqc中(1)標示的 popen 將執(zhí)行命令的標準輸出定向到了 logfile 中,由于 popen 會 fork 一個進程去執(zhí)行 popen 參數(shù) command 指定的程序,一般子進程標準輸出不重定向的情況下,子進程的標準輸出與父進程相同,子進程可以從標準輸入中得到父進程傳遞的數(shù)據(jù)流(通過管道),并且也可通過子進程輸出到標準輸出,在 logfile 中父進程可以知道子進程的輸出結果。request 函數(shù)實現(xiàn)讀取數(shù)據(jù)調(diào)用處理程序并將數(shù)據(jù)寫入管道的功能。

清單 2. 進程 B 部分源代碼(fileB.sqc)

static int npRead(FILE * fp , int i )
{
int iLen = 3;
int iRetLen = 0;
int ireadLen =0 ;
char buflen[3+1];
char buffer[100];
memset( buffer , 0x00 , sizeof( buffer ));
memset( buflen , 0x00 , sizeof( buflen ));
ireadLen = … .;
…
ireadLen = fread( buffer , sizeof( char ) , iRetLen , stdin );
…
buffer[iRetLen] = 0x00;
…
// 輸出到與父進程相同的 LOG 文件中
printf( "recv[%d][%s]\n" ,iRetLen ,buffer );
… .
return 0;
}
void nGetNetData()
{
int i = 0;
for ( i = 0; i < n ; i++ )
{
npRead( stdin , i );
}
}
進程 B 調(diào)用 nGetNetData 函數(shù)就可以從標準輸入到進程 A 傳遞數(shù)據(jù)了,并且在 npRead 中通過調(diào)用 printf 
將日志信息輸出到了在進程 A 中指定的文件 logfile 中。

結束語

1、使用匿名管道并結合我們常用標準輸入輸出函數(shù)實現(xiàn)進程間通訊很方便,但不適用于無親緣關系的進程。

2、對于管道兩端的進程而言,就是一個文件,但它不是普通的文件,它不屬于某種文件系統(tǒng),而是單獨構成一種文件系統(tǒng),并且只存在內(nèi)存中,通信雙方的進程通過標準輸入輸出 API 進行通信寫入和讀取。

3、管道也是一種文件類型,理解其原理更有利于我們使用它。

4、標準輸入輸出和普通的文件描述符相同,我們可以根據(jù)需要利用 shell 或者 dup 函數(shù)都可以實現(xiàn)重定向。這樣我們就可以更好的利用標準 I/O 庫為我們工作了。

原文:

http://www.ibm.com/developerworks/cn/aix/library/1106_chenye_commbypipe/index.html?ca=drs-

【編輯推薦】

  1. 實戰(zhàn):排除 AIX 服務器的故障
  2. 甲骨文拋棄安騰可能是IBM AIX業(yè)務的機會?
  3. 教您如何在AIX上卸載DB2數(shù)據(jù)庫
責任編輯:黃丹 來源: IBMDW
相關推薦

2012-05-22 15:55:41

AIXiSCSI

2017-08-16 20:44:23

大數(shù)據(jù)虛擬化數(shù)據(jù)分析

2024-01-29 17:02:10

數(shù)據(jù)治理大數(shù)據(jù)數(shù)據(jù)工程

2021-04-12 13:07:36

數(shù)據(jù)治理數(shù)據(jù)資產(chǎn)CIO

2013-07-03 09:39:07

產(chǎn)品優(yōu)化產(chǎn)品通過數(shù)據(jù)優(yōu)化產(chǎn)品

2021-01-22 10:58:16

網(wǎng)絡安全進程間碼如

2024-01-03 10:17:51

Linux通信

2019-05-13 10:00:41

Linux進程間通信命令

2021-09-30 10:45:33

Linux進程通信

2023-10-31 17:50:58

2009-04-28 19:46:16

LinuxAIX服務器

2020-11-04 07:17:42

Nodejs通信進程

2021-04-26 15:43:59

數(shù)據(jù)驅(qū)動智能樓宇樓宇自動化

2023-08-30 10:56:59

數(shù)字化轉(zhuǎn)型物流

2013-03-28 13:14:45

AIDL進程間通信Android使用AI

2013-09-17 18:27:27

SAP

2010-04-28 17:54:07

aix系統(tǒng)

2010-11-01 14:54:49

DB2數(shù)據(jù)導入

2022-03-13 08:52:07

數(shù)據(jù)安全數(shù)據(jù)泄露

2020-02-24 15:06:13

亞馬遜數(shù)據(jù)湖AWS
點贊
收藏

51CTO技術棧公眾號