[C#]I/O完成端口的类定义和测试实例

<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>

从William Kennedy那里整理过来的,不同之处在于他自己定义了一个Overlapped,而我们这里直接使用
System.Threading.NativeOverlapped.

附一段我以前的Win32下的IOCP文档,如果您了解IOCP也可以直接跳过看后面的C#测试示范:

整理者:郑昀@UltraPower

我们采用的是I/O Complete Port(以下简称IOCP)处理机制。

简单的讲,当服务应用程序初始化时,它应该先创建一个I/O CP。我们在请求到来后,将得到的数据打包用PostQueuedCompletionStatus发送到IOCP中。这时需要创建一些个线程(7个线程/CPU,再多就没有意义了)来处理发送到IOCP端口的消息。实现步骤大致如下:

1 先在主线程中调用CreateIoCompletionPort创建IOCP

CreateIoCompletionPort的前三个参数只在把设备同Complete Port相关联时才有用。

此时我们只需传递INVALID_HANDLE_VALUE,NULL0即可。

第四个参数告诉端口同时能运行的最多线程数,这里设置为0,表示默认为当前计算机的CPU数目。

2 我们的ThreadFun线程函数执行一些初始化之后,将进入一个循环,该循环会在服务进程终止时才结束。

在循环中,调用GetQueuedCompletionStatus,这样就把当前线程的ID放入一个等待线程队列中,I/O CP内核对象就总能知道哪个线程在等待处理完成的I/O请求。

如果在IDLE_THREAD_TIMEOUT规定的时间内I/O CP上还没有出现一个Completion Packet,则转入下一次循环。在这里我们设置的IDLE_THREAD_TIMEOUT1秒。

当端口的I/O完成队列中出现一项时,完成端口就唤醒等待线程队列中的这个线程,该线程将得到完成的I/O项中的信息: 传输的字节数、完成键和OVERLAPPED结构的地址。

在我们的程序中可以用智能指针或者BSTR或者int来接受这个OVERLAPPED结构的地址的值,从而得到消息;然后在这个线程中处理消息。

GetQueuedCompletionStatus的第一个参数hCompletionPort指出了要监视哪一个端口,这里我们传送先前从CreateIoCompletionPort返回的端口句柄。

需要注意的是:

第一, 线程池的数目是有限制的,和CPU数目有关系。

第二, IOCP是一种较为完美的睡眠/唤醒 线程机制;线程当前没有任务要处理时,就进入睡眠状态,从而不占用CPU资源,直到被内核唤醒;

第三, 最近一次刚执行完的线程,下次任务来的时候还会唤醒它;所以有可能比较少被调用的线程以后被调用的几率也少。


测试代码:


using System;
using System.Threading; // IncludedfortheThread.Sleepcall
using Continuum.Threading;
using System.Runtime.InteropServices;

namespace IOCPDemo
{
//=============================================================================
/**////<summary></summary>Sampleclassforthethreadingclass
publicclassUtilThreadingSample
{
//*****************************************************************************
/**////<summary></summary>TestMethod
staticvoidMain()
{
//CreatetheMSSQLIOCPThreadPool
IOCPThreadPoolpThreadPool=newIOCPThreadPool(0,10,20,newIOCPThreadPool.USER_FUNCTION(IOCPThreadFunction));

//for(inti=1;i
{
pThreadPool.PostEvent(
1234);
}


Thread.Sleep(
100);

pThreadPool.Dispose();
}


//********************************************************************
/**////<summary></summary>FunctiontobecalledbytheIOCPthreadpool.Calledwhen
///acommandispostedforprocessingbytheSocketManager
///Thevalueprovidedbythethreadpostingtheevent

staticpublicvoidIOCPThreadFunction(intiValue)
{
try
{
Console.WriteLine(
"Value:{0}",iValue.ToString());
Thread.Sleep(
3000);
}


catch(ExceptionpException)
{
Console.WriteLine(pException.Message);
}

}

}


}



类代码:
using System;
using System.Threading;
using System.Runtime.InteropServices;

namespace IOCPThreading
{
[StructLayout(LayoutKind.Sequential,CharSet
=CharSet.Auto)]

publicsealedclassIOCPThreadPool
{
[DllImport(
"Kernel32",CharSet=CharSet.Auto)]
privateunsafestaticexternUInt32CreateIoCompletionPort(UInt32hFile,UInt32hExistingCompletionPort,UInt32*puiCompletionKey,UInt32uiNumberOfConcurrentThreads);

[DllImport(
"Kernel32",CharSet=CharSet.Auto)]
privateunsafestaticexternBooleanCloseHandle(UInt32hObject);

[DllImport(
"Kernel32",CharSet=CharSet.Auto)]
privateunsafestaticexternBooleanPostQueuedCompletionStatus(UInt32hCompletionPort,UInt32uiSizeOfArgument,UInt32*puiUserArg,System.Threading.NativeOverlapped*pOverlapped);

[DllImport(
"Kernel32",CharSet=CharSet.Auto)]
privateunsafestaticexternBooleanGetQueuedCompletionStatus(UInt32hCompletionPort,UInt32*pSizeOfArgument,UInt32*puiUserArg,System.Threading.NativeOverlapped**ppOverlapped,UInt32uiMilliseconds);

privateconstUInt32INVALID_HANDLE_VALUE=0xffffffff;
privateconstUInt32INIFINITE=0xffffffff;
privateconstInt32SHUTDOWN_IOCPTHREAD=0x7fffffff;
publicdelegatevoidUSER_FUNCTION(intiValue);
privateUInt32m_hHandle;
privateUInt32GetHandle{get{returnm_hHandle;}set{m_hHandle=value;}}

privateInt32m_uiMaxConcurrency;

privateInt32GetMaxConcurrency{get{returnm_uiMaxConcurrency;}set{m_uiMaxConcurrency=value;}}


privateInt32m_iMinThreadsInPool;

privateInt32GetMinThreadsInPool{get{returnm_iMinThreadsInPool;}set{m_iMinThreadsInPool=value;}}

privateInt32m_iMaxThreadsInPool;

privateInt32GetMaxThreadsInPool{get{returnm_iMaxThreadsInPool;}set{m_iMaxThreadsInPool=value;}}


privateObjectm_pCriticalSection;

privateObjectGetCriticalSection{get{returnm_pCriticalSection;}set{m_pCriticalSection=value;}}


privateUSER_FUNCTIONm_pfnUserFunction;

privateUSER_FUNCTIONGetUserFunction{get{returnm_pfnUserFunction;}set{m_pfnUserFunction=value;}}


privateBooleanm_bDisposeFlag;

/**////<summary></summary>SimType:Flagtoindicateiftheclassisdisposing

privateBooleanIsDisposed{get{returnm_bDisposeFlag;}set{m_bDisposeFlag=value;}}

privateInt32m_iCurThreadsInPool;

/**////<summary></summary>SimType:Thecurrentnumberofthreadsinthethreadpool

publicInt32GetCurThreadsInPool{get{returnm_iCurThreadsInPool;}set{m_iCurThreadsInPool=value;}}

/**////<summary></summary>SimType:Incrementcurrentnumberofthreadsinthethreadpool

privateInt32IncCurThreadsInPool(){returnInterlocked.Increment(refm_iCurThreadsInPool);}

/**////<summary></summary>SimType:Decrementcurrentnumberofthreadsinthethreadpool</span
分享到:
评论
happmaoo
  • 浏览: 1285342 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

你可能感兴趣的:(thread,数据结构,C++,c,C#)