多线程编程(4)--从CreateThread说起(倒数第三个参数)

转载自:万一的博客

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

    



  线程入口函数的参数是一个无类型指针(Pointer),用它可以指定任何数据(这就是指针强大的地方之一);本例是把鼠标点击窗体的坐标传递给线程的入口函数,每次点击窗体都会创建一个线程,运行效果图如下

  代码如下

unit Unit1;

interface
uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
    TForm1=class(TForm)
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
            Shift: TShiftState; X, Y: Integer);
    end;

var
    Form1: TForm1;

implementation
{$R *.dfm}

var
    pt: TPoint;    //这个坐标点将会以指针的方式传递给线程,它应该是全局的

function MyThreadFun(p: Pointer): Integer; stdcall;
var
    i: Integer;
    pt2: TPoint;        //因为指针参数给的点随时都在变,需要线程的局部变量存起来
begin
    pt2:= PPoint(p)^;    //转换
    for i:=0 to 1000000 do
    begin
        with Form1.Canvas do begin
            Lock;
            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);
var
    ID: DWORD;
begin
    pt:= Point(X, Y);
    CreateThread(nil, 0, @MyThreadFun, @pt, 0, ID);
    //下面的写法更好理解,其实不必,因为 PPoint会自动转换为 Pointer的
    //CreateThread(nil, 0, @MyThreadFun, Pointer(@pt), 0, ID);
end;

end.

    

  窗体文件

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = ‘Form1‘
  ClientHeight = 128
  ClientWidth = 229
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = ‘Tahoma‘
  Font.Style = []
  OldCreateOrder = False
  OnMouseUp = FormMouseUp
  PixelsPerInch = 96
  TextHeight = 13
end

    



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

  另外一个小技巧:线程函数的参数是个 32位(4个字节)的指针,仅就本例来说,可以让它的“高16位”和 “低16位” 分别携带X 和Y ,这样就不需要那个全局的pt 变量了。

  其实在 Windows 的消息中就是这样传递坐标的,在Windows的消息中一般高字节是 Y、低字节是X ;咱们这么来吧,这样还可以使用给消息准备的一些方便的函数

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

unit Unit1;

interface
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
    TForm1=class(TForm)
        procedure FormMouseUp(Sender: Tobject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    end;

var
    Form1: TForm1;

implementation
{$R *.dfm}

function MyThreadFun(p: Pointer): Integer; stdcall;
var
    i: Integer;            //Integer是32bit,4个字节
    x, y: Word;            //word是16bit,2个字节
begin
    x:= LoWord(Integer(p));    //将p转换为Integer,并获取其低字节
    y:= HiWord(Integer(p));    //类似上面

    {如果不使用LoWord、HiWord函数,则可以向下面这样:}
    //x:= Integer(p);
    //y:= Integer(p) shr 16;

    for i:= 0 to 1000000 do
    begin
        With Form1.Canvas do begin
            Lock;
            TextOut(x, y, IntToStr(i));
            UnLock;
        end;
    end;
    Result:= 0;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
var
    ID: DWORD;
    num: Integer;
begin
    num:= MakeLong(X, Y);
    {如果不使用MakeLong、MakeWParam、MakeLParam、MakeResult等函数,可以像下面这样:}
    //num:= Y shl 16 +X;
    CreateThread(nil, 0, @MuThreadFun, Ptr(num), 0, ID);
    {上面的 Ptr 是专门讲一个数字转换为指针的函数,当然也可以这样}
    //CreateThread(nil, 0, @MyThreadFun, Pointer(num), 0, ID);
end;

end.

   

时间: 2024-10-03 06:56:01

多线程编程(4)--从CreateThread说起(倒数第三个参数)的相关文章

多线程编程(3)--从CreateThread说起(倒数第二个参数)

转载自:万一的博客 function CreateThread( lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; {启动选项} var lpThreadId: DWORD ): THandle; stdcall; CreateThread的倒数第二个参数dwCreateFlasg

多线程编程(2)--从CreateThread说起

转载自:万一的博客 function CreateThread( lpThreadAttributes: Pointer; //安全设置 dwStackSize: DWORD; //堆栈大小 lpStartAddress: TFNThreadStartRoutine; //入口函数 lpParameter: Pointer; //函数参数 dwCreationFlags: DWORD; //启动选项 var lpThreadId: DWORD; //输出线程ID ): THandle; stdc

【转】iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD

转自容芳志的博客 简介 iOS有三种多线程编程的技术,分别是: (一)NSThread (二)Cocoa NSOperation (三)GCD(全称:Grand Central Dispatch) 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的. 三种方式的优缺点介绍: 1)NSThread: 优点:NSThread 比其他两个轻量级 缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 NSThread实现的技术

iOS有三种多线程编程的技术

1.NSThread 2.NSOperationQueue 3.GCD Thread 是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步.线程共享同一应用程序的部分内存空间, 它们拥有对数据相同的访问权限.你得协调多个线程对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销.在 iOS 中我们可以使用多种形式的 thread: Cocoa threads: 使用NSThread 或直接从 NSObject 的类方法 perfo

iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD

简介iOS有三种多线程编程的技术,分别是:(一)NSThread(二)Cocoa NSOperation(三)GCD(全称:Grand Central Dispatch) 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的. 三种方式的优缺点介绍:1)NSThread:优点:NSThread 比其他两个轻量级缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 NSThread实现的技术有下面三种:一般使用cocoa

多线程编程基础知识

多线程编程基础知识 http://www.cnblogs.com/cy163/archive/2006/11/02/547428.html 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.因此掌握

delphi之多线程编程(尚未学习)

本文的内容取自网络,并重新加以整理,在此留存仅仅是方便自己学习和查阅.所有代码均亲自测试 delphi7下测试有效.图片均为自己制作. 多线程应该是编程工作者的基础技能, 但这个基础我从来没学过,所以仅仅是看上去会一些,明白了2+2的时候,其实我还不知道1+1. 开始本应该是一篇洋洋洒洒的文字, 不过我还是提倡先做起来, 在尝试中去理解.先试试这个:  procedure TForm1.Button1Click(Sender: TObject); var   i: Integer; begin 

delphi 多线程编程

开始本应该是一篇洋洋洒洒的文字, 不过我还是提倡先做起来, 在尝试中去理解.先试试这个: procedure TForm1.Button1Click(Sender: TObject); var i: Integer; begin for i := 0 to 500000 do begin Canvas.TextOut(10, 10, IntToStr(i)); end; end; 上面程序运行时, 我们的窗体基本是 "死" 的, 可以在你在程序运行期间拖动窗体试试... Delphi

多线程编程1

参考资料: http://blog.csdn.net/JXH_123/article/details/23450031                             秒杀多线程系列 http://www.baidu.com/index.php?tn=utf8kb_oem_dg&addresssearch=1#wd=C%2B%2B%E5%BE%AA%E7%8E%AF%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97&ie=utf-8&tn=utf8kb