管道实现进程间通讯 、WaitNamedPipe
一、管道实现进程间通讯
主要的理论知识
1.什么是管道以及分类
api,结果操作管道就和操作文件一样。即使你在不同的计算机之间用命名管道来通信,你也不必了解和自己去实现网络间通信的详细细节。
2.管道的使用
A.命名管道
命名管道是由server端的进程建立的,管道的命名必须遵循特定的命名方法,就是"//./pipe/管道名",当作为client的进程要使用时,使用"//计算机名//pipe/管道名"来打开使用,详细过程例如以下:
服务端通过函数CreateNamedPipe创建一个命名管道的实例并返回用于今后操作的句柄,或为已存在的管道创建新的实例。服务端侦听来自client的连接请求,该功能通过ConnectNamedPipe函数实现。
client通过函数WaitNamedPipe来等待管道的出现,假设在超时值变为零曾经,有一个管道能够使用,则WaitNamedPipe将返回
True,并通过调用CreateFile或CallNamedPipe来呼叫对服务端的连接。
此时服务端将接受client的连接请求,成功建立连接,服务端ConnectNamedPipe返回
True 建立连接之后,client与server端就可以通过ReadFile和WriteFile,利用得到的管道文件句柄,彼此间进行信息交换。当client与服务端的通信结束,client调用CloseFile,服务端接着调用DisconnectNamedPipe。最后调用函数CloseHandle来关闭该管道。
B.匿名管道
因为命名管道使用时作为client的程序必须知道管道的名称,所以很多其它的用在同一“作者”编写的server/工作站程序中,你不可能随便找出一个程序来要求它和你写的程序来通过命名管道通信。而匿名管道的使用则全然不同,它同意你和全然不相干的进程通信,条件是这个进程通过控制台“console”来输入输出,典型的样例是老的
Dos 应用程序,它们在执行时 Windows为它们开了个
Dos窗体,它们的输入输出就是 console方式的。另一些标准的 Win32程序也使用控制台输入输出,假设在
Win32编程中不想使用图形界面,你照样能够使用AllocConsole得到一个控制台,然后通过GetStdHandle得到输入或输出句柄,再通过WriteConsole或WriteFile把结果输出到控制台(一般是一个象
Dos窗体)的屏幕上。尽管这些程序看起来象 Dos程序,但它们是不折不扣的 Win32程序,假设你在纯
Dos下使用,就会显示“The program must run under Windows!”。
一个控制台有三个句柄:标准输入、标准输出和和标准错误句柄,标准输入、标准输出句柄是能够又一次定向的,你能够用匿名管道来取代它,这样一来,你能够在管道的还有一端用别的进程来接收或输入,而控制台一方并没有感到什么不同,就象
Dos下的 >或者 <能够又一次定向输出或输入一样。通常控制台程序的输入输出例如以下:
(控制台进程output)
write ----> 标准输出设备(通常是屏幕)
(控制台进程input)
read <---- 标准输入设备(通常是键盘)
write ----> 管道1 ----> read (父进程)
read <----> 管道2 <---- write (父进程)
使用匿名管道的过程例如以下:
hStdInput,第二个取代 hStdOutput、hStdError,即标准输入、输出、错误句柄
WriteFile写第一个管道来将输入写到子进程
管道使用的API函数集
|
|||||||
|
|||||||
|
|||||||
|
|||||||
|
|||||||
|
|||||||
|
|||||||
|
|||||||
|
|||||||
|
|||||||
|
二、
BOOL WaitNamedPipe( LPCTSTR lpNamedPipeName, DWORD nTimeOut );
lpNamedPipeName 要打开的管道名,格式\\servername\pipe\pipename,假设是本地管道则servername能够使用点“.”。
nTimeOut 等待命名管道的一个实例有效的超时时间,单位毫秒,也能够使用以下两个值中的一个:
NMPWAIT_USE_DEFAULT_WAIT 0x00000000,使用服务端CreateNamedPipe 创建管道时设置的超时时间。
NMPWAIT_WAIT_FOREVER 0xffffffff,一直等到一个命名管道的实例有效才返回。
返回值:
假设在超时时间前管道的一个实例有效,返回非0。
假设超时时间内没有一个有效的实例,返回0。
注意:
假设指定的命名管道没有实例存在,即没有服务端创建该命名管道(所以在确定server端创建了该命名管道时能够不调用此API),函数无视超时等待时间直接返回0。
假设函数运行成功返回TRUE,表示至少有一个命名管道的实例有效,接下来应该使用CreateFile函数打开命名管道的一个句柄,可是CreateFile可能会打开管道失败,由于该实例有可能被服务端关闭或被已经被其它client打开。
三、管道使用的伤痛所在
static inline BOOL
CTPipe_WriteNBytes(HANDLE hPipe, BYTE *buf, DWORD size, DWORD timeout, HANDLE stopEvent)
{
BOOL ret = FALSE;
BOOL writeRet;
OVERLAPPED ol;
BYTE *pos;
DWORD cbBytesWrite;
HANDLE hWriteEvent; memset( &ol, 0, sizeof(ol) );
ol.hEvent = hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if ( ol.hEvent == NULL )
{
return FALSE;
} pos = buf;
while ( size > 0 )
{
writeRet = WriteFile(hPipe,
pos,
size,
&cbBytesWrite,
&ol);
if ( writeRet )
{
pos += cbBytesWrite;
size -= cbBytesWrite;
ResetEvent(hWriteEvent);
}
else
{
if ( GetLastError() == ERROR_IO_PENDING )
{
DWORD waitRet;
HANDLE handles[2];
int numOfHandles = 1; handles[0] = hWriteEvent;
if ( stopEvent )
{
handles[1] = stopEvent;
numOfHandles++;
} waitRet = WaitForMultipleObjects(numOfHandles, handles, FALSE, timeout);
if ( waitRet == WAIT_OBJECT_0 )
{
writeRet = GetOverlappedResult(hPipe, &ol, &cbBytesWrite, TRUE );
if ( writeRet == FALSE )
{
goto EXIT;
}
pos += cbBytesWrite;
size -= cbBytesWrite;
ResetEvent(hWriteEvent);
}
else /* timeout, notify event or other */
{
/*
* Cancel request
*/
if ( CancelIo(hPipe) == FALSE )
{
L_ERROR(_T("IoCancel fail 0x%x, force close pipe\n"), GetLastError());
CloseHandle(hPipe);
}
else
{
/*
* Wait cannel finish
*/
GetOverlappedResult(hPipe, &ol, &cbBytesWrite, TRUE);
}
goto EXIT;
}
}
else
{
goto EXIT;
}
}
}
ret = TRUE; EXIT:
if ( hWriteEvent )
{
CloseHandle(hWriteEvent);
}
return ret;
}
在
waitRet = WaitForMultipleObjects(numOfHandles, handles, FALSE, timeout);
发生了堵塞,此管理是採用异步的,这里写的管道是作为服务端,问题是服务端的代码根本就没有变,倒是管道client的代码变了。
hPipe = CreateNamedPipe("Name",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
0,
0,
0, /*XENHANCE_PIPE_TIMEOUT*/
&sa);
法一、在服务端的管道写时设置超时时间,这尽管能使用服务端管道的线程不卡死,但也可能该写的数据没有写进去。
1、
2、
3、
4、
5、
6、
7、
管道实现进程间通讯 、WaitNamedPipe的更多相关文章
- 【IPC进程间通讯之二】管道Pipe
IPC进程间通信+管道Pipe IPC(Inter-Process Communication.进程间通信). 管道用于进程间共享数据,事实上质是共享内存 ...
- [转]Windows 下的进程间通讯及数据共享
http://blog.codingnow.com/2005/10/interprocess_communications.html Windows 下有很多方法实现进程间通讯,比如用 socket, ...
- windows 进程间通讯方法
Windows平台为我们提供了多种进程间通信的机制,主要包括:注册表方式.共享文件方式.共享内存方式.共享数据段.映射文件方式.管道方式. 剪贴板方式.消息方式.其中注册表方式需要增加注册表表项,而注 ...
- C#进程间通讯技术-整理。
原文:C#进程间通讯技术-整理. 扩展阅读:http://www.cnblogs.com/joye-shen/archive/2012/06/16/2551864.html 一.进程间通讯的方式 1) ...
- C# 进程间通讯
扩展阅读:http://www.cnblogs.com/joye-shen/archive/2012/06/16/2551864.html 一.进程间通讯的方式 1)共享内存 包括:内存映射文件,共享 ...
- Python-互斥锁 进程间通讯
3.守护进程(**) 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常: AssertionError: daemonic proces ...
- Linux 进程间通讯
一.Linux 下进程间通讯方式 1)管道(Pipe)及有名管道(named pipe): 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
- 守护进程,进程安全,IPC进程间通讯,生产者消费者模型
1.守护进程(了解)2.进程安全(*****) 互斥锁 抢票案例3.IPC进程间通讯 manager queue(*****)4.生产者消费者模型 守护进程 指的也是一个进程,可以守护着另一个进程 一 ...
- 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制【转】
本文转载自:https://blog.csdn.net/freekiteyu/article/details/70082302 Android-Binder进程间通讯机制 概述 最近在学习Binder ...
随机推荐
- Unity3d 网络编程(二)(Unity3d内建网络各项參数介绍)
这里是全部Unity3d在网络中能用到相关的类及方法.纵观參数功能, Unity3d来写一个手游是不二的选择: RPC 能够传递的參数 int float string NetworkPlayer N ...
- 以前学习cisco ccna 课程的时候做的笔记
由于学习的专业是计算机网络技术,可是在上学的时候,并没有学习到多少网络知识,所以为了对得起学的专业,在06年工作的时候,在哈工大银河教育报了个ccna的班,两个星期的课程,每天上那么几个小时. 结果依 ...
- UITableViewHeaderFooterView的使用+自己主动布局
UITableViewHeaderFooterView的使用+自己主动布局 使用UITableView的header或footer复用时,假设採用自己主动布局,你会发现有约束冲突,以下这样写能够消除约 ...
- 一个带动画效果的颜色选择对话框控件AnimatedColorPickerDialog
android4.4的日历中选择日程显示颜色的时候有一个颜色选择对话框非常漂亮,模仿他的界面我实现了一个类似的对话框,而且带有动画效果. 代码的实现可讲的地方不多,主要是采用了和AlertDialog ...
- 《大象UML》看书笔记2:
<大象UML>看书笔记2 抽象角度: 在为现实世界建模的时候,首先要搞清楚有多 ...
- c:foreach如何嵌套循环,求指教,求优化
java类: public class PopedomItem { private String id; private String pid; private String name; privat ...
- 免解压版的Mysql的启动脚本,并且执行导入(windows)
@echo off rem ################### set MYSQL_VERSION=mysql-5.5.32-win32 set LOCK=wot.lock rem ####### ...
- iPhone5C三大看点:性能不输iPhone5 或售3399元
乐杨俊编辑修改转载: iPhone 5C的发售时间或最早在9月18日,抢在中秋节前:最迟至国庆十一假期期间. [IT商业新闻网综合讯](记者 林涛)苹果2013年秋季发布会还有几个小时即将开幕,除了i ...
- POJ - 1006 Biorhythms 周期相遇 两个思路程序
Description Some people believe that there are three cycles in a person's life that start the day he ...
- vc怎么去掉烦人的“驱动器未准备好”错误
在我们写程序的时候,如果访问一个软驱中没有软盘或者光驱中没有cd的时候,windows总是弹出一个恼人的错误框说“驱动器未准备好” 其实我们可以通过如下的步骤禁止这个错误框的弹出 一.用SetErro ...