进程间通信之异步管道
来源:互联网 发布:mac pro双系统玩游戏 编辑:程序博客网 时间:2024/06/14 03:56
异步管道实现的流程图说明:
1)。父进程是我们需要实现的,其中需要创建管道A,管道B,和子进程,整个实现流程分为4个操作。
2)。管道A:输入管道
3)。管道B:输出管道
4)。操作A:把输入文件sample.in的数据写入输入管道(管道A)
5)。操作B:子进程从输入管道中读取数据,作为该进程的加工原料。通常,程序的输入数据由标准的输入设备输入,这里实现输入重定向,即把输入管道作为输入设备。
6)。操作C:子进程把加工后的成品(输出数据)输出到输出管道。通常,程序的输出数据会输出到标准的输出设备,一般为屏幕,这里实现输出重定向,即把输出管道作为输出设备。
7)。操作D:把输出管道的数据写入输出文件
需要注意的是,管道的本质只是一个共享的内存区域。这个实验中,管道区域处于父进程的地址空间中,父进程的作用是提供环境和资源,并协调子进程进行加工。
sample.exe实现:
#include <iostream.h>
int main()
{
int a, b ;
while ( cin >> a >> b && ( a || b ) )
cout << a + b << endl ;
return 0;
}
Sample.in文件是输入文件,内容:
32 433
542 657
0 0
程序运行:
pipe.exe sample.exe sample.in sample.out
主程序pipe代码:
#include <windows.h>
#include <iostream.h>
const int BUFSIZE = 4096 ;
HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd,hChildStdoutWr,hChildStdoutRdDup,
hSaveStdin, hSaveStdout;
BOOL CreateChildProcess(LPTSTR);
VOID WriteToPipe(LPTSTR);
VOID ReadFromPipe(LPTSTR);
VOID ErrorExit(LPTSTR);
VOID ErrMsg(LPTSTR, BOOL);
void main( int argc, char *argv[] )
{
// 处理输入参数
if ( argc != 4 )
return ;
// 分别用来保存命令行,输入文件名(CPP/C),输出文件名(保存编译信息)
LPTSTR lpProgram = new char( sizeof(argv[1]) ) ;
strcpy ( lpProgram, argv[1] ) ;
LPTSTR lpInputFile = new char( sizeof(argv[2]) ) ;
strcpy ( lpInputFile, argv[2] ) ;
LPTSTR lpOutputFile = new char( sizeof(argv[3]) ) ;
strcpy ( lpOutputFile, argv[3] ) ;
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
/************************************************
* redirecting child process's STDOUT *
************************************************/
hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
ErrorExit("Stdout pipe creation failed\n");
if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
ErrorExit("Redirecting STDOUT failed");
BOOL fSuccess = DuplicateHandle(
GetCurrentProcess(),
hChildStdoutRd,
GetCurrentProcess(),
&hChildStdoutRdDup ,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
if( !fSuccess )
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdoutRd);
/************************************************
* redirecting child process's STDIN *
************************************************/
hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
ErrorExit("Stdin pipe creation failed\n");
if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
ErrorExit("Redirecting Stdin failed");
fSuccess = DuplicateHandle(
GetCurrentProcess(),
hChildStdinWr,
GetCurrentProcess(),
&hChildStdinWrDup,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
if (! fSuccess)
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdinWr);
/************************************************
* 创建子进程(即启动SAMPLE.EXE) *
************************************************/
fSuccess = CreateChildProcess( lpProgram );
if ( !fSuccess )
ErrorExit("Create process failed");
// 父进程输入输出流的还原设置
if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
ErrorExit("Re-redirecting Stdin failed\n");
if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
ErrorExit("Re-redirecting Stdout failed\n");
WriteToPipe( lpInputFile ) ;
ReadFromPipe( lpOutputFile );
}
BOOL CreateChildProcess( LPTSTR lpProgram )
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bFuncRetn = FALSE;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
bFuncRetn = CreateProcess ( NULL, lpProgram, NULL, NULL, TRUE, \
0, NULL, NULL, &siStartInfo, &piProcInfo);
if (bFuncRetn == 0)
{
ErrorExit("CreateProcess failed\n");
return 0;
}
else
{
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
return bFuncRetn;
}
}
VOID WriteToPipe( LPTSTR lpInputFile )
{
HANDLE hInputFile = CreateFile(lpInputFile, GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if (hInputFile == INVALID_HANDLE_VALUE)
return ;
BOOL fSuccess ;
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE] = {0} ;
for (;;)
{
fSuccess = ReadFile( hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ;
if ( !fSuccess || dwRead == 0)
break;
fSuccess = WriteFile( hChildStdinWrDup, chBuf, dwRead, &dwWritten, NULL) ;
if ( !fSuccess )
break;
}
if (! CloseHandle(hChildStdinWrDup))
ErrorExit("Close pipe failed\n");
CloseHandle ( hInputFile ) ;
}
VOID ReadFromPipe( LPTSTR lpOutputFile )
{
HANDLE hOutputFile = CreateFile( lpOutputFile, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutputFile == INVALID_HANDLE_VALUE)
return ;
BOOL fSuccess ;
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE] = { 0 };
if (!CloseHandle(hChildStdoutWr))
ErrorExit("Closing handle failed");
for (;;)
{
fSuccess = ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead, NULL) ;
if( !fSuccess || dwRead == 0)
{
break;
}
fSuccess = WriteFile( hOutputFile, chBuf, dwRead, &dwWritten, NULL) ;
if ( !fSuccess )
break;
}
CloseHandle ( hOutputFile ) ;
}
VOID ErrorExit (LPTSTR lpszMessage)
{
MessageBox( 0, lpszMessage, 0, 0 );
}
- 进程间通信之异步管道
- [进程通信] 进程间通信 之 管道
- Windows系统编程之进程间通信-异步管道和命名管道
- 进程间通信之管道
- 进程间通信之 管道
- 进程间通信 之 管道
- 进程间通信之管道
- 进程间通信之管道
- 进程间通信之 管道
- 进程间通信之管道
- 进程间通信之管道
- 进程间通信之管道
- 进程间通信之管道
- 进程间通信之管道
- 进程间通信之管道
- 进程间通信之--- 管道
- 进程间通信之管道
- 进程间通信之管道
- hdu 1007 Quoit Design(二维 最近点对)
- 一个能够自动给pdf生成目录的东西
- 百度2013校园招聘笔试题[软件研发类]及分析
- TextField 常用
- sqlsever 2008
- 进程间通信之异步管道
- 字符串排序
- php 多太性
- S3C6410 Memory Map & ARM 指令集 笔记
- 安卓经典盈利模式
- 如何促进长尾词的文字收录呢
- shell 多进程机制
- 浅谈新网站如何有效进行网站外链建设
- android ListView,GridView 使用小结