上一次问线程的句柄问题有哥们回帖:
CloseHandle释放的是线程内核对象,并不是将线程停止,所以用了CloseHandle之后,你不能再用这个内核对象进行相关的操作,但是线程本身还会运行。
这里所说的加1减1是指对线程内核对象的引用值加1。不要将线程内核对象与线程混为一谈
我对“线程本身还会运行”很怀疑,因为线程执行完计数-1,计数器才可能达到0,也就是线程执行完了才可能释放线程内核对象问题2:对于一个普通的HANDLE 文件、管道、邮槽……
(1)HANDLE hXX;这时hXX的内核对象的计数器是多少?
(2)hXX=CreatePipe…… 这时内核对象的计数器是多少?
经历了以上2步后调用CloseHandle(hXX);
(3)hXX = NULL;这时计数器是多少?给一个句柄赋值NULL会引起对应内核对象计数器变化吗?
CloseHandle释放的是线程内核对象,并不是将线程停止,所以用了CloseHandle之后,你不能再用这个内核对象进行相关的操作,但是线程本身还会运行。
这里所说的加1减1是指对线程内核对象的引用值加1。不要将线程内核对象与线程混为一谈
我对“线程本身还会运行”很怀疑,因为线程执行完计数-1,计数器才可能达到0,也就是线程执行完了才可能释放线程内核对象问题2:对于一个普通的HANDLE 文件、管道、邮槽……
(1)HANDLE hXX;这时hXX的内核对象的计数器是多少?
(2)hXX=CreatePipe…… 这时内核对象的计数器是多少?
经历了以上2步后调用CloseHandle(hXX);
(3)hXX = NULL;这时计数器是多少?给一个句柄赋值NULL会引起对应内核对象计数器变化吗?
问题2,HANDLE是一种数据类型,可以用来储存句柄值,也就是内核对象的索引值。就像一个int变量可以作为数组的下标,但不能把int变量看作数组元素一样。
(1)HANDLE hXX,这是定义HANDLE型变量hXX,并未给hXX赋值,该变量值无意义。
(2)hXX=CreatePipe,如果创建成功,内核对象计数器是1;如果失败,则没有分配内核对象。
(3)hXX = NULL,给变量赋值为NULL,即为空,此后hXX不是有效的句柄值,也不代表任何内核对象。给HANDLE型变量赋值只会应该该变量,不会影响到变量原值对应的内核对象。
在CNamedPipeSrvView中+一个句柄hPipe在构造函数中:
CNamedPipeSrvView::CNamedPipeSrvView()
{
// TODO: add construction code here
hPipe=NULL;//第一次
}
在创建管道是用上
void CNamedPipeSrvView::OnPipeCreate()
{
// TODO: Add your command handler code here
hPipe=CreateNamedPipe("\\\\.\\pipe\\MyPipe",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
0,1,1024,1024,0,NULL);//第二次
if(INVALID_HANDLE_VALUE==hPipe)
{
MessageBox("创建命名管道失败!");
hPipe=NULL;
return;
}
HANDLE hEvent;
hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!hEvent)
{
MessageBox("创建事件对象失败!");
CloseHandle(hPipe);//可能的第三次
hPipe=NULL;//这里行的通吗?
return;
}
OVERLAPPED ovlap;
ZeroMemory(&ovlap,sizeof(OVERLAPPED));
ovlap.hEvent=hEvent;
if(!ConnectNamedPipe(hPipe,&ovlap))
{
if(ERROR_IO_PENDING!=GetLastError())
{
MessageBox("等待客户端连接失败!");
CloseHandle(hPipe);
CloseHandle(hEvent);
hPipe=NULL;
return;
}
}
if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))
{
MessageBox("等待对象失败!");
CloseHandle(hPipe);
CloseHandle(hEvent);
hPipe=NULL;
return;
}
CloseHandle(hEvent);
}
最后析构函数中CNamedPipeSrvView::~CNamedPipeSrvView()
{
if(hPipe)
CloseHandle(hPipe);
}