首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

关于关闭管道的有关问题DisconnectNamedPipe

2012-05-16 
关于关闭管道的问题DisconnectNamedPipe我使用了等待模式在线程中创建了管道,并等待客户端连接,连接成功后

关于关闭管道的问题DisconnectNamedPipe
我使用了等待模式在线程中创建了管道,并等待客户端连接,连接成功后开始读取管道数据:
//首先:创建线程
m_hThread = CreateThread(NULL, 0, ThredFkt, this, 0, &m_nThreadID);


//线程函数
DWORD WINAPI CMyPipe::ThredFkt(LPVOID lpParameter)
{
  CMyPipe* pThis = (CMyPipe*)lpParameter;

  pThis->ReadPipe(); // 创建管道并监听客户端连接

  return 0;
}

//创建管道,并等待客户端连接后读取管道数据
bool CMyPipe::ReadMyPipe()
{
  m_hPipe = CreateNamedPipe(g_csPipeName, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, 
  PIPE_UNLIMITED_INSTANCES, 0, 0, 200, NULL);

  if (ConnectNamedPipe(m_hPipe, NULL) == FALSE)
  return false;

  DWORD nReaded = 0;
  char csPrefix[MAX_PATH];
  char buffer[512];
  while (ReadFile(m_hPipe, buffer, sizeof(buffer)-1, &nReaded, NULL))
  {
  ...
  //我在这里面有调用了CMyPipe的成员变量
  ...
  }
  SetEvent(m_hMsgEvent); // 发送消息,通知线程处理结束
  return true;
}

//析构函数
CMyPipe::~CMyPipe(void)
{
  ResetEvent(m_hMsgEvent); // 重置消息句柄
  DisconnectNamedPipe(m_hPipe); // 关闭管道
  WaitForSingleObject(m_hMsgEvent, INFINITE); // 等待线程退出 ???这边会被卡住
}


但是现在有个很奇怪的问题就是我在析构中调用了DisconnectNamedPipe()和WaitForSingleObject(),结果发现管道没有被关闭,没有执行SetEvent(m_hMsgEvent),导致了WaitForSingleObject()一直等待。

请教下是不是DisconnectNamedPipe()这个调用后不能马上调用WaitForSingleObject()等待。。。
由于我在while (ReadFile(m_hPipe, buffer, sizeof(buffer)-1, &nReaded, NULL))这个while里面有调用了CMyPipe的成员,如果我在析构中不等待线程先退出的话,会导致析构后如果while中调用了类的成员会崩掉。。。

请问下这种情况下应该怎么处理。。。我需要管道服务端主动断开与客户端的连接。。。


补充下:
我试了下分开调用DisconnectNamedPipe()和WaitForSingleObject(),不放在同一个函数里面,就可以通过,不会被卡住。

[解决办法]
你不应该在析构方法中调用WaitForSingleObject,而且你的这几段代码中也没有必要使用等待事件
[解决办法]
接着补充一下:为什么使用事件对象不可以呢,比如说服务端与客户端传输数据的时候,突然关闭了服务端,这样是不可能执行下面的那个SetEvent函数的,这样得不到通知,当然是会卡住的!
[解决办法]
WaitForSingleObject(m_hMsgEvent, 0)的等待时间为0,会马上返回不会阻塞,在msdn上查查WaitForSingleObject的用法和如何检查它的返回值吧。

热点排行