• (转)C#实现IOCP


    C#实现IOCP(完成端口)的详细代码如下:

    using System;
    using System.Threading; // Included for the Thread.Sleep call
    using Continuum.Threading;
    namespace Sample
    {
    //============================================
    /// <summary> Sample class for the threading class </summary>
    public class UtilThreadingSample
    {
    //*******************************************
    /// <summary> Test Method </summary>
    static void Main()
    {
    // Create the MSSQL IOCP Thread Pool
    IOCPThreadPool pThreadPool = new IOCPThreadPool(0, 5, 10, new IOCPThreadPool.USER_FUNCTION(IOCPThreadFunction));
    pThreadPool.PostEvent(
    10);
    Thread.Sleep(
    100);
    pThreadPool.Dispose();
    }
    //*****************************************
    /// <summary> Function to be called by the IOCP thread pool. Called when
    /// a command is posted for processing by the SocketManager </summary>
    /// <param name="iValue"> The value provided by the thread posting the event </param>
    static public void IOCPThreadFunction(Int32 iValue)
    {
    try
    {
    Console.WriteLine(
    "Value: {0}", iValue);
    }
    catch (Exception pException)
    {
    Console.WriteLine(pException.Message);
    }
    }
    }
    }

    using System;
    using System.Threading;
    using System.Runtime.InteropServices;

    namespace Continuum.Threading
    {

    // Structures
    //==========================================
    /// <summary> This is the WIN32 OVERLAPPED structure </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public unsafe struct OVERLAPPED
    {
    UInt32
    * ulpInternal;
    UInt32
    * ulpInternalHigh;
    Int32 lOffset;
    Int32 lOffsetHigh;
    UInt32 hEvent;
    }

    // Classes
    //============================================
    /// <summary> This class provides the ability to create a thread pool to manage work. The
    /// class abstracts the Win32 IOCompletionPort API so it requires the use of
    /// unmanaged code. Unfortunately the .NET framework does not provide this functionality </summary>
    public sealed class IOCPThreadPool
    {

    // Win32 Function Prototypes
    /// <summary> Win32Func: Create an IO Completion Port Thread Pool </summary>
    [DllImport("Kernel32", CharSet = CharSet.Auto)]
    private unsafe static extern UInt32 CreateIoCompletionPort(UInt32 hFile, UInt32 hExistingCompletionPort, UInt32* puiCompletionKey, UInt32 uiNumberOfConcurrentThreads);

    /// <summary> Win32Func: Closes an IO Completion Port Thread Pool </summary>
    [DllImport("Kernel32", CharSet = CharSet.Auto)]
    private unsafe static extern Boolean CloseHandle(UInt32 hObject);

    /// <summary> Win32Func: Posts a context based event into an IO Completion Port Thread Pool </summary>
    [DllImport("Kernel32", CharSet = CharSet.Auto)]
    private unsafe static extern Boolean PostQueuedCompletionStatus(UInt32 hCompletionPort, UInt32 uiSizeOfArgument, UInt32* puiUserArg, OVERLAPPED* pOverlapped);

    /// <summary> Win32Func: Waits on a context based event from an IO Completion Port Thread Pool.
    /// All threads in the pool wait in this Win32 Function </summary>
    [DllImport("Kernel32", CharSet = CharSet.Auto)]
    private unsafe static extern Boolean GetQueuedCompletionStatus(UInt32 hCompletionPort, UInt32* pSizeOfArgument, UInt32* puiUserArg, OVERLAPPED** ppOverlapped, UInt32 uiMilliseconds);

    // Constants
    /// <summary> SimTypeConst: This represents the Win32 Invalid Handle Value Macro </summary>
    private const UInt32 INVALID_HANDLE_VALUE = 0xffffffff;

    /// <summary> SimTypeConst: This represents the Win32 INFINITE Macro </summary>
    private const UInt32 INIFINITE = 0xffffffff;

    /// <summary> SimTypeConst: This tells the IOCP Function to shutdown </summary>
    private const Int32 SHUTDOWN_IOCPTHREAD = 0x7fffffff;



    // Delegate Function Types
    /// <summary> DelType: This is the type of user function to be supplied for the thread pool </summary>
    public delegate void USER_FUNCTION(Int32 iValue);


    // Private Properties
    private UInt32 m_hHandle;
    /// <summary> SimType: Contains the IO Completion Port Thread Pool handle for this instance </summary>
    private UInt32 GetHandle { get { return m_hHandle; } set { m_hHandle = value; } }

    private Int32 m_uiMaxConcurrency;
    /// <summary> SimType: The maximum number of threads that may be running at the same time </summary>
    private Int32 GetMaxConcurrency { get { return m_uiMaxConcurrency; } set { m_uiMaxConcurrency = value; } }

    private Int32 m_iMinThreadsInPool;
    /// <summary> SimType: The minimal number of threads the thread pool maintains </summary>
    private Int32 GetMinThreadsInPool { get { return m_iMinThreadsInPool; } set { m_iMinThreadsInPool = value; } }

    private Int32 m_iMaxThreadsInPool;
    /// <summary> SimType: The maximum number of threads the thread pool maintains </summary>
    private Int32 GetMaxThreadsInPool { get { return m_iMaxThreadsInPool; } set { m_iMaxThreadsInPool = value; } }

    private Object m_pCriticalSection;
    /// <summary> RefType: A serialization object to protect the class state </summary>
    private Object GetCriticalSection { get { return m_pCriticalSection; } set { m_pCriticalSection = value; } }

    private USER_FUNCTION m_pfnUserFunction;
    /// <summary> DelType: A reference to a user specified function to be call by the thread pool </summary>
    private USER_FUNCTION GetUserFunction { get { return m_pfnUserFunction; } set { m_pfnUserFunction = value; } }

    private Boolean m_bDisposeFlag;
    /// <summary> SimType: Flag to indicate if the class is disposing </summary>
    private Boolean IsDisposed { get { return m_bDisposeFlag; } set { m_bDisposeFlag = value; } }

    // Public Properties
    private Int32 m_iCurThreadsInPool;
    /// <summary> SimType: The current number of threads in the thread pool </summary>
    public Int32 GetCurThreadsInPool { get { return m_iCurThreadsInPool; } set { m_iCurThreadsInPool = value; } }
    /// <summary> SimType: Increment current number of threads in the thread pool </summary>
    private Int32 IncCurThreadsInPool() { return Interlocked.Increment(ref m_iCurThreadsInPool); }
    /// <summary> SimType: Decrement current number of threads in the thread pool </summary>
    private Int32 DecCurThreadsInPool() { return Interlocked.Decrement(ref m_iCurThreadsInPool); }
    private Int32 m_iActThreadsInPool;
    /// <summary> SimType: The current number of active threads in the thread pool </summary>
    public Int32 GetActThreadsInPool { get { return m_iActThreadsInPool; } set { m_iActThreadsInPool = value; } }
    /// <summary> SimType: Increment current number of active threads in the thread pool </summary>
    private Int32 IncActThreadsInPool() { return Interlocked.Increment(ref m_iActThreadsInPool); }
    /// <summary> SimType: Decrement current number of active threads in the thread pool </summary>
    private Int32 DecActThreadsInPool() { return Interlocked.Decrement(ref m_iActThreadsInPool); }
    private Int32 m_iCurWorkInPool;
    /// <summary> SimType: The current number of Work posted in the thread pool </summary>
    public Int32 GetCurWorkInPool { get { return m_iCurWorkInPool; } set { m_iCurWorkInPool = value; } }
    /// <summary> SimType: Increment current number of Work posted in the thread pool </summary>
    private Int32 IncCurWorkInPool() { return Interlocked.Increment(ref m_iCurWorkInPool); }
    /// <summary> SimType: Decrement current number of Work posted in the thread pool </summary>
    private Int32 DecCurWorkInPool() { return Interlocked.Decrement(ref m_iCurWorkInPool); }



    // Constructor, Finalize, and Dispose
    //***********************************************
    /// <summary> Constructor </summary>
    /// <param name = "iMaxConcurrency"> SimType: Max number of running threads allowed </param>
    /// <param name = "iMinThreadsInPool"> SimType: Min number of threads in the pool </param>
    /// <param name = "iMaxThreadsInPool"> SimType: Max number of threads in the pool </param>
    /// <param name = "pfnUserFunction"> DelType: Reference to a function to call to perform work </param>
    /// <exception cref = "Exception"> Unhandled Exception </exception>
    public IOCPThreadPool(Int32 iMaxConcurrency, Int32 iMinThreadsInPool, Int32 iMaxThreadsInPool, USER_FUNCTION pfnUserFunction)
    {
    try
    {
    // Set initial class state
    GetMaxConcurrency = iMaxConcurrency;
    GetMinThreadsInPool
    = iMinThreadsInPool;
    GetMaxThreadsInPool
    = iMaxThreadsInPool;
    GetUserFunction
    = pfnUserFunction;
    // Init the thread counters
    GetCurThreadsInPool = 0;
    GetActThreadsInPool
    = 0;
    GetCurWorkInPool
    = 0;
    // Initialize the Monitor Object
    GetCriticalSection = new Object();
    // Set the disposing flag to false
    IsDisposed = false;
    unsafe
    {
    // Create an IO Completion Port for Thread Pool use
    GetHandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, null, (UInt32)GetMaxConcurrency);
    }
    // Test to make sure the IO Completion Port was created
    if (GetHandle == 0)
    throw new Exception("Unable To Create IO Completion Port");
    // Allocate and start the Minimum number of threads specified
    Int32 iStartingCount = GetCurThreadsInPool;
    ThreadStart tsThread
    = new ThreadStart(IOCPFunction);
    for (Int32 iThread = 0; iThread < GetMinThreadsInPool; ++iThread)
    {
    // Create a thread and start it
    Thread thThread = new Thread(tsThread);
    thThread.Name
    = "IOCP " + thThread.GetHashCode();
    thThread.Start();
    // Increment the thread pool count
    IncCurThreadsInPool();
    }
    }
    catch
    {
    throw new Exception("Unhandled Exception");
    }
    }

    //***********************************************
    /// <summary> Finalize called by the GC </summary>
    ~IOCPThreadPool()
    {
    if (!IsDisposed)
    Dispose();
    }

    //**********************************************
    /// <summary> Called when the object will be shutdown. This
    /// function will wait for all of the work to be completed
    /// inside the queue before completing </summary>
    public void Dispose()
    {
    try
    {
    // Flag that we are disposing this object
    IsDisposed = true;
    // Get the current number of threads in the pool
    Int32 iCurThreadsInPool = GetCurThreadsInPool;
    // Shutdown all thread in the pool
    for (Int32 iThread = 0; iThread < iCurThreadsInPool; ++iThread)
    {
    unsafe
    {
    bool bret = PostQueuedCompletionStatus(GetHandle, 4, (UInt32*)SHUTDOWN_IOCPTHREAD, null);
    }
    }
    // Wait here until all the threads are gone
    while (GetCurThreadsInPool != 0) Thread.Sleep(100);
    unsafe
    {
    // Close the IOCP Handle
    CloseHandle(GetHandle);
    }
    }
    catch
    {
    }
    }

    // Private Methods
    //*******************************************
    /// <summary> IOCP Worker Function that calls the specified user function </summary>
    private void IOCPFunction()
    {
    UInt32 uiNumberOfBytes;
    Int32 iValue;
    try
    {
    while (true)
    {
    unsafe
    {
    OVERLAPPED
    * pOv;
    // Wait for an event
    GetQueuedCompletionStatus(GetHandle, &uiNumberOfBytes, (UInt32*)&iValue, &pOv, INIFINITE);
    }
    // Decrement the number of events in queue
    DecCurWorkInPool();
    // Was this thread told to shutdown
    if (iValue == SHUTDOWN_IOCPTHREAD)
    break;
    // Increment the number of active threads
    IncActThreadsInPool();
    try
    {
    // Call the user function
    GetUserFunction(iValue);
    }
    catch
    {
    }
    // Get a lock
    Monitor.Enter(GetCriticalSection);
    try
    {
    // If we have less than max threads currently in the pool
    if (GetCurThreadsInPool < GetMaxThreadsInPool)
    {
    // Should we add a new thread to the pool
    if (GetActThreadsInPool == GetCurThreadsInPool)
    {
    if (IsDisposed == false)
    {
    // Create a thread and start it
    ThreadStart tsThread = new ThreadStart(IOCPFunction);
    Thread thThread
    = new Thread(tsThread);
    thThread.Name
    = "IOCP " + thThread.GetHashCode();
    thThread.Start();
    // Increment the thread pool count
    IncCurThreadsInPool();
    }
    }
    }
    }
    catch
    {
    }
    // Relase the lock
    Monitor.Exit(GetCriticalSection);
    // Increment the number of active threads
    DecActThreadsInPool();
    }
    }
    catch
    {
    }
    // Decrement the thread pool count
    DecCurThreadsInPool();
    }

    // Public Methods
    //******************************************
    /// <summary> IOCP Worker Function that calls the specified user function </summary>
    /// <param name="iValue"> SimType: A value to be passed with the event </param>
    /// <exception cref = "Exception"> Unhandled Exception </exception>
    public void PostEvent(Int32 iValue)
    {
    try
    {
    // Only add work if we are not disposing
    if (IsDisposed == false)
    {
    unsafe
    {
    // Post an event into the IOCP Thread Pool
    PostQueuedCompletionStatus(GetHandle, 4, (UInt32*)iValue, null);
    }
    // Increment the number of item of work
    IncCurWorkInPool();
    // Get a lock
    Monitor.Enter(GetCriticalSection);
    try
    {
    // If we have less than max threads currently in the pool
    if (GetCurThreadsInPool < GetMaxThreadsInPool)
    {
    // Should we add a new thread to the pool
    if (GetActThreadsInPool == GetCurThreadsInPool)
    {
    if (IsDisposed == false)
    {
    // Create a thread and start it
    ThreadStart tsThread = new ThreadStart(IOCPFunction);
    Thread thThread
    = new Thread(tsThread);
    thThread.Name
    = "IOCP " + thThread.GetHashCode();
    thThread.Start();
    // Increment the thread pool count
    IncCurThreadsInPool();
    }
    }
    }
    }
    catch
    {
    }
    // Release the lock
    Monitor.Exit(GetCriticalSection);
    }
    }
    catch (Exception e)
    {
    throw e;
    }
    catch
    {
    throw new Exception("Unhandled Exception");
    }
    }
    //*****************************************
    /// <summary> IOCP Worker Function that calls the specified user function </summary>
    /// <exception cref = "Exception"> Unhandled Exception </exception>
    public void PostEvent()
    {
    try
    {
    // Only add work if we are not disposing
    if (IsDisposed == false)
    {
    unsafe
    {
    // Post an event into the IOCP Thread Pool
    PostQueuedCompletionStatus(GetHandle, 0, null, null);
    }
    // Increment the number of item of work
    IncCurWorkInPool();
    // Get a lock
    Monitor.Enter(GetCriticalSection);
    try
    {
    // If we have less than max threads currently in the pool
    if (GetCurThreadsInPool < GetMaxThreadsInPool)
    {
    // Should we add a new thread to the pool
    if (GetActThreadsInPool == GetCurThreadsInPool)
    {
    if (IsDisposed == false)
    {
    // Create a thread and start it
    ThreadStart tsThread = new ThreadStart(IOCPFunction);
    Thread thThread
    = new Thread(tsThread);
    thThread.Name
    = "IOCP " + thThread.GetHashCode();
    thThread.Start();
    // Increment the thread pool count
    IncCurThreadsInPool();
    }
    }
    }
    }
    catch
    {
    }
    // Release the lock
    Monitor.Exit(GetCriticalSection);
    }
    }
    catch (Exception e)
    {
    throw e;
    }
    catch
    {
    throw new Exception("Unhandled Exception");
    }
    }
    }
    }

    以上就是C#实现IOCP(完成端口)的详细代码示例,希望对你有所帮助。

  • 相关阅读:
    VS自带的dbghelp.h文件 报错
    Windows 自带的截屏功能
    CentOS 7 安装
    Windows 远程连接 CentOS 7 图形化桌面
    <<、|=、&的小例子
    pip 安装库过慢
    pip -i 和 -U 参数
    windows下安装TA-Lib库
    vector、map 判断某元素是否存在、查找指定元素
    vector push_back报错
  • 原文地址:https://www.cnblogs.com/lscy/p/1856535.html
Copyright © 2020-2023  润新知