热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

IOCP做的高效率线程池类源码:GThreadPool

{*********************************************************************************GThradPool

{********************************************************************************
*     GThradPool:完成端口线程池                                       *
*   Copyright C 2009  GuestCode 代码客(卢益贵)  版权所有                *
*  QQ:48092788  E-Mail:gcode@qq.com  源码博客:http://blog.csdn.net/guestcode   *
********************************************************************************}

unit GThreadPool;

interface

uses
  Windows, Classes;

type
  PGThread =^ TGThread;
  TGThread = record
    pOwner: Pointer;
    pNext: PGThread;
    ThreadHnd: THandle;
    ThreadID: DWord;
    pData: pointer;
  end;

  TGThreadPool = class
  private
    FCompletionPort: THandle;
    FThreads: PGThread;
    FThreadNumber: Integer;
    FIsShutdown: BOOL;
    FAllowPost: BOOL;
    FQueueCount: Integer;
  protected
    procedure OnThreadBegin(Thread: DWord); virtual;
    procedure OnThreadEnd(Thread: DWord); virtual;
    procedure OnRun(pData: Pointer; Sender, wParam, lParam: DWord); virtual;
  public
    constructor Create(ThreadNumber: Integer); virtual;
    destructor Destroy(); override;
    procedure SetData(Thread: DWord; pData: Pointer);
    function GetData(Thread: DWord): Pointer; overload;
    function GetData(): Pointer; overload;
    function PostQueue(Sender, wParam, lParam: DWord): BOOL;
  end;

implementation

{ TGThreadPool }

function GThreadPoolProc(pThread: PGThread): DWORD; stdcall;
var
  Sender, wParam, lParam: DWord;
begin
  with pThread^, TGThreadPool(pOwner) do
  begin
    OnThreadBegin(DWORD(pThread));
    while True do
    begin
      GetQueuedCompletionStatus(FCompletionPort, Sender, DWORD(wParam), POverlapped(lParam), INFINITE);
      if FIsShutdown then
        break;
      OnRun(pData, Sender, wParam, lParam);
      InterlockedDecrement(FQueueCount);
    end;
    OnThreadEnd(DWORD(pThread));
  end;
  Result := 0;
  SetEvent(pThread^.ThreadHnd);
end;

constructor TGThreadPool.Create(ThreadNumber: Integer);
var
  i: Integer;
  pThread: PGThread;
begin
  inherited Create();

  FIsShutdown := False;
  FAllowPost := TRUE;
  FQueueCount := 0;
  if ThreadNumber <1 then
    ThreadNumber := 1;
  FThreadNumber := ThreadNumber;
  FCompletionPort := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, ThreadNumber);

  FThreads := nil;
  for i := 1 to FThreadNumber do
  begin
    GetMem(pThread, sizeof(TGThread));
    ZeroMemory(pThread, sizeof(TGThread));
    pThread^.pNext := FThreads;
    FThreads := pThread;
    pThread^.pOwner := self;
    pThread^.ThreadHnd := CreateThread(nil, 0, @GThreadPoolProc, pThread, 0, pThread^.ThreadID);
  end;
end;

destructor TGThreadPool.Destroy();
var
  pThread, tmp: PGThread;
begin
  FAllowPost := FALSE;
   
  while FQueueCount <> 0 do
  begin
    Sleep(1);
  end;

  FIsShutdown := True;
 
  pThread := FThreads;
  while (pThread <> nil) do
  begin
    PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil);
    pThread := pThread^.pNext;
  end;
 
  pThread := FThreads;
  while (pThread <> nil) do
  begin
    WaitForSingleObject(pThread^.ThreadHnd, INFINITE);
    pThread := pThread^.pNext;
  end;
 
  pThread := FThreads;
  while (pThread <> nil) do
  begin

    CloseHandle(pThread^.ThreadHnd);
    tmp := pThread;
    pThread := pThread^.pNext;
    FreeMem(tmp);
  end;
 
  CloseHandle(FCompletionPort);
  inherited;
end;

procedure TGThreadPool.OnThreadBegin(Thread: DWord);
begin
end;

procedure TGThreadPool.OnThreadEnd(Thread: DWord);
begin
end;

procedure TGThreadPool.OnRun(pData: Pointer; Sender, wParam, lParam: DWord);
begin
end;

function TGThreadPool.PostQueue(Sender, wParam, lParam: DWord): BOOL;
begin
  if FAllowPost then
  begin
    PostQueuedCompletionStatus(FCompletionPort, Sender, wParam, Pointer(lParam));
    InterlockedIncrement(FQueueCount);
    Result := True;
  end else
  begin
    Result := False;
  end;
end;

procedure TGThreadPool.SetData(Thread: DWord; pData: Pointer);
begin
  PGThread(Thread)^.pData := pData;
end;

function TGThreadPool.GetData(): Pointer;
var
  pThread: PGThread;
  ThreadID: DWord;
begin
  pThread := FThreads;
  ThreadID := GetCurrentThreadId();
  while (pThread <> nil) do
  begin
    if pThread^.ThreadID = ThreadID then
    begin
      Result := pThread^.pData;
      exit;
    end;
    pThread := pThread^.pNext;
  end;
  Result := nil;
end;

function TGThreadPool.GetData(Thread: DWord): Pointer;
begin
  Result := PGThread(Thread)^.pData;
end;

end.

 

 


推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
author-avatar
手机用户2602936797
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有