function CreateThread(lpThreadAttributes: Pointer;dwStackSize: DWORD;lpStartAddress: TFNThreadStartRoutine;lpParameter: Pointer;  {入口函数的参数}dwCreationFlags: DWORD;var lpThreadId: DWORD
): THandle; stdcall;

线程入口函数的参数是个无类型指针(Pointer), 用它可以指定任何数据; 本例是把鼠标点击窗体的坐标传递给线程的入口函数, 每次点击窗体都会创建一个线程.

运行效果图:



代码文件:


unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs;typeTForm1 = class(TForm)procedure FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);end;varForm1: TForm1;implementation{$R *.dfm}varpt: TPoint; {这个坐标点将会已指针的方式传递给线程, 它应该是全局的}function MyThreadFun(p: Pointer): Integer; stdcall;
vari: Integer;pt2: TPoint;       {因为指针参数给的点随时都在变, 需用线程的局部变量存起来}
beginpt2 := PPoint(p)^; {转换}for i := 0 to 1000000 dobeginwith Form1.Canvas do beginLock;TextOut(pt2.X, pt2.Y, IntToStr(i));Unlock;end;end;Result := 0;
end;procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
varID: DWORD;
beginpt := Point(X, Y);CreateThread(nil, 0, @MyThreadFun, @pt, 0, ID);{下面这种写法更好理解, 其实不必, 因为 PPoint 会自动转换为 Pointer 的}//CreateThread(nil, 0, @MyThreadFun, Pointer(@pt), 0, ID);
end;end.

窗体文件:


object Form1: TForm1Left = 0Top = 0Caption = 'Form1'ClientHeight = 128ClientWidth = 229Color = clBtnFaceFont.Charset = DEFAULT_CHARSETFont.Color = clWindowTextFont.Height = -11Font.Name = 'Tahoma'Font.Style = []OldCreateOrder = FalseOnMouseUp = FormMouseUpPixelsPerInch = 96TextHeight = 13
end

这个例子还有不严谨的地方: 当一个线程 Lock 窗体的 Canvas 时, 其他线程在等待; 线程在等待时, 其中的计数也还在增加. 这也就是说: 现在并没有去处理线程的同步; 同步是多线程中最重要的课题, 快到了.

另外有个小技巧: 线程函数的参数是个 32 位(4个字节)的指针, 仅就本例来讲, 可以让它的 "高16位" 和 "低16位" 分别携带 X 和 Y; 这样就不需要哪个全局的 pt 变量了.
其实在 Windows 的消息中就是这样传递坐标的, 在 Windows 的消息中一般高字节是 Y、低字节是 X; 咱们这么来吧, 这样还可以使用给消息准备的一些方便的函数.

重写本例代码(当然运行效果和窗体文件都是一样的):


unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs;typeTForm1 = class(TForm)procedure FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);end;varForm1: TForm1;implementation{$R *.dfm}function MyThreadFun(p: Pointer): Integer; stdcall;
vari: Integer;x,y: Word;
beginx := LoWord(Integer(p));y := HiWord(Integer(p));{如果不使用 LoWord、HiWord 函数可以像下面这样: }//x := Integer(p);//y := Integer(p) shr 16;for i := 0 to 1000000 dobeginwith Form1.Canvas do beginLock;TextOut(x, y, IntToStr(i));Unlock;end;end;Result := 0;
end;procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
varID: DWORD;num: Integer;
beginnum := MakeLong(X, Y);{如果不使用 MekeLong、MakeWParam、MakeLParam、MakeResult 等函数, 可以像下面这样: }//num := Y shl 16 + X;CreateThread(nil, 0, @MyThreadFun, Ptr(num), 0, ID);{上面的 Ptr 是专门将一个数字转换为指针的函数, 当然也可以这样: }//CreateThread(nil, 0, @MyThreadFun, Pointer(num), 0, ID);
end;end.

转载于:https://www.cnblogs.com/del/archive/2009/02/11/1388008.html

多线程编程(4) - 从 CreateThread 说起[续二]相关推荐

  1. 多线程编程(7) - 从 CreateThread 说起[续五]

    function CreateThread(lpThreadAttributes: Pointer; {安全设置}dwStackSize: DWORD;lpStartAddress: TFNThrea ...

  2. 多线程编程学习笔记——任务并行库(二)

    接上文 多线程编程学习笔记--任务并行库(一) 三.   组合任务 本示例是学习如何设置相互依赖的任务.我们学习如何创建一个任务的子任务,这个子任务必须在父任务执行结束之后,再执行. 1,示例代码如下 ...

  3. C++使用Windows API CreateMutex函数多线程编程

    C++中也可以使用Windows 系统中对应的API函数进行多线程编程.使用CreateThread函数创建线程,并且可以通过CreateMutex创建一个互斥量实现线程间数据的同步: #includ ...

  4. 多线程编程学习笔记——async和await(三)

    接上文 多线程编程学习笔记--async和await(一) 接上文 多线程编程学习笔记--async和await(二) 五.   处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...

  5. 多线程编程学习笔记——任务并行库(三)

    接上文 多线程编程学习笔记--任务并行库(一) 接上文 多线程编程学习笔记--任务并行库(二) 六.   实现取消选项 本示例学习如何实现基于Task的异步操作进行取消流程,以及在任务真正运行前如何知 ...

  6. 多线程编程学习笔记——使用并发集合(三)

    接上文 多线程编程学习笔记--使用并发集合(一) 接上文 多线程编程学习笔记--使用并发集合(二) 四.   使用ConcurrentBag创建一个可扩展的爬虫 本示例在多个独立的即可生产任务又可消费 ...

  7. 多线程编程CreateThread和_beginthreadex用法

    多线程编程 1.CreateThread HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, //内核对象的安全 ...

  8. [转]Linux 的多线程编程的高效开发经验

    Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...

  9. 多线程编程有什么用途_C++ 多线程编程 (一)

    What is thread? In computer science, a thread of execution is the smallest sequence of programmed in ...

  10. C++使用thread类多线程编程

    目录 pthread多线程 系统自带CreateThread std::thread c++ 多线程总结_jacke121的专栏-CSDN博客 std thread比较好用,但是系统带的socket不 ...

最新文章

  1. Java集合7 (NavigableSet)
  2. mysql 连接 分组_详解MySQL中的分组查询与连接查询语句
  3. Hadoop安装记录(伪分布式)
  4. gitlab 删除分支_初识gitlab工作流
  5. Redis与Memcache的区别
  6. pythonc代码_Python实现C代码统计工具(一)
  7. Android的SharedPreferences存取String和List<String>类型(在Activity和Fragment内使用)
  8. IKVM.NET_第一篇_概述
  9. 网上打开与关闭gps几种方案测试,其中方案3可行
  10. activex 控件 过期_ie8/9下Activex控件无法加载的两种解决方法
  11. 惠普HPE服务器升级iLO4固件版本
  12. win7 删除网络计算机,win7系统修改和删除网络图标的方法
  13. oracle12c的特点,Oracle12c新特点详述
  14. 绊脚石乃是进身之阶 jzoj 2017.8.15 B组
  15. Windows 本地账户
  16. BJOI2019 勘破神机 新解
  17. 【Homeassistant 与Ultrasonic Distance超声波距离传感器握手】
  18. Choco求解器的安装
  19. 【优化布局】matlab基于禁忌搜索算法求解基站选址问题代码
  20. 附近的人打招呼V1.0

热门文章

  1. Canonical发布信息图:Ubuntu Linux连接一切
  2. MultiRow发现之旅(五)- MultiRow版俄罗斯方块(exe + 源码)
  3. java关于map用来筛选的用法
  4. 也谈UpdatePanel与UrlRewrite一起work时出现Form Action属性的问题
  5. 【Caffe】caffe框架讲解,解析修改caffemodel与prototxt
  6. CentOS安装Nginx 报错“configure: error: the HTTP rewrite module requires the PCRE library”解决办法...
  7. STL中的序列式容器——vector(向量)
  8. 记录MySql错误消息
  9. 基于nodejs的模拟数据分发服务
  10. delphi2010:按键 控制键 组合键的判断 响应