多线程编程(4) - 从 CreateThread 说起[续二]
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 说起[续二]相关推荐
- 多线程编程(7) - 从 CreateThread 说起[续五]
function CreateThread(lpThreadAttributes: Pointer; {安全设置}dwStackSize: DWORD;lpStartAddress: TFNThrea ...
- 多线程编程学习笔记——任务并行库(二)
接上文 多线程编程学习笔记--任务并行库(一) 三. 组合任务 本示例是学习如何设置相互依赖的任务.我们学习如何创建一个任务的子任务,这个子任务必须在父任务执行结束之后,再执行. 1,示例代码如下 ...
- C++使用Windows API CreateMutex函数多线程编程
C++中也可以使用Windows 系统中对应的API函数进行多线程编程.使用CreateThread函数创建线程,并且可以通过CreateMutex创建一个互斥量实现线程间数据的同步: #includ ...
- 多线程编程学习笔记——async和await(三)
接上文 多线程编程学习笔记--async和await(一) 接上文 多线程编程学习笔记--async和await(二) 五. 处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...
- 多线程编程学习笔记——任务并行库(三)
接上文 多线程编程学习笔记--任务并行库(一) 接上文 多线程编程学习笔记--任务并行库(二) 六. 实现取消选项 本示例学习如何实现基于Task的异步操作进行取消流程,以及在任务真正运行前如何知 ...
- 多线程编程学习笔记——使用并发集合(三)
接上文 多线程编程学习笔记--使用并发集合(一) 接上文 多线程编程学习笔记--使用并发集合(二) 四. 使用ConcurrentBag创建一个可扩展的爬虫 本示例在多个独立的即可生产任务又可消费 ...
- 多线程编程CreateThread和_beginthreadex用法
多线程编程 1.CreateThread HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, //内核对象的安全 ...
- [转]Linux 的多线程编程的高效开发经验
Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...
- 多线程编程有什么用途_C++ 多线程编程 (一)
What is thread? In computer science, a thread of execution is the smallest sequence of programmed in ...
- C++使用thread类多线程编程
目录 pthread多线程 系统自带CreateThread std::thread c++ 多线程总结_jacke121的专栏-CSDN博客 std thread比较好用,但是系统带的socket不 ...
最新文章
- Java集合7 (NavigableSet)
- mysql 连接 分组_详解MySQL中的分组查询与连接查询语句
- Hadoop安装记录(伪分布式)
- gitlab 删除分支_初识gitlab工作流
- Redis与Memcache的区别
- pythonc代码_Python实现C代码统计工具(一)
- Android的SharedPreferences存取String和List<String>类型(在Activity和Fragment内使用)
- IKVM.NET_第一篇_概述
- 网上打开与关闭gps几种方案测试,其中方案3可行
- activex 控件 过期_ie8/9下Activex控件无法加载的两种解决方法
- 惠普HPE服务器升级iLO4固件版本
- win7 删除网络计算机,win7系统修改和删除网络图标的方法
- oracle12c的特点,Oracle12c新特点详述
- 绊脚石乃是进身之阶 jzoj 2017.8.15 B组
- Windows 本地账户
- BJOI2019 勘破神机 新解
- 【Homeassistant 与Ultrasonic Distance超声波距离传感器握手】
- Choco求解器的安装
- 【优化布局】matlab基于禁忌搜索算法求解基站选址问题代码
- 附近的人打招呼V1.0
热门文章
- Canonical发布信息图:Ubuntu Linux连接一切
- MultiRow发现之旅(五)- MultiRow版俄罗斯方块(exe + 源码)
- java关于map用来筛选的用法
- 也谈UpdatePanel与UrlRewrite一起work时出现Form Action属性的问题
- 【Caffe】caffe框架讲解,解析修改caffemodel与prototxt
- CentOS安装Nginx 报错“configure: error: the HTTP rewrite module requires the PCRE library”解决办法...
- STL中的序列式容器——vector(向量)
- 记录MySql错误消息
- 基于nodejs的模拟数据分发服务
- delphi2010:按键 控制键 组合键的判断 响应