在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!
  如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的。但是,你应该明白,在每个线程中动态分配和销毁内存块,是需要同步保护的。Delphi语言中有一个在使用多线程环境下至关重要的全局变量IsMultiThread,系统在进行内存分配的时候,根据IsMultiThread变量值判断当前是否使用在多线程环境下,如果该变量为True,哪么,系统在分配和销毁内存的时候,是要进行同步保护的。相反,则不用同步保护。
  所以,如果你直接使用CreateThread()创建线程,一定要记得手动将IsMultiThread变量置为True。要不然你就会经常发现系统内存非法访问错误!如果你使用Delphi中的BeginThread()创建线程,这个BeginThread()的实现如下:
function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
  ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord;
  var ThreadId: LongWord): Integer;
var
  P: PThreadRec;
begin
  New(P);
  P.Func := ThreadFunc;
  P.Parameter := Parameter;
  IsMultiThread := TRUE;
  Result := CreateThread(SecurityAttributes, StackSize, @ThreadWrapper, P,
    CreationFlags, ThreadID);
end;
  看见了吗?上面已经将IsMultiThread := TRUE;这样就保证了在多线程下,内存使用的安全。
  使用BeginThread()函数替代CreateThread()的另一个重要理由就在上面的的代码段中,你发现了吗?BeginThread()函数内部在调用CreateThread()的时候,哪个线程函数指针用的是@ThreadWrapper,参数用的是P,而 P: PThreadRec;  是一个结构体指针,结构体内部分别才是线程函数和线程函数参数。
  ThreadWrapper函数实现如下:
{$IFDEF MSWINDOWS}
function ThreadWrapper(Parameter: Pointer): Integer; stdcall;
{$ELSE}
function ThreadWrapper(Parameter: Pointer): Pointer; cdecl;
{$ENDIF}
asm
{$IFDEF PC_MAPPED_EXCEPTIONS}
        { Mark the top of the stack with a signature }
        PUSH    UNWINDFI_TOPOFSTACK
{$ENDIF}
        CALL    _FpuInit
        PUSH    EBP
{$IFNDEF PC_MAPPED_EXCEPTIONS}
        XOR     ECX,ECX
        PUSH    offset _ExceptionHandler
        MOV     EDX,FS:[ECX]
        PUSH    EDX
        MOV     FS:[ECX],ESP
{$ENDIF}
{$IFDEF PC_MAPPED_EXCEPTIONS}
    // The signal handling code in SysUtils depends on being able to
    // discriminate between Delphi threads and foreign threads in order
    // to choose the disposition of certain signals.  It does this by
    // testing a TLS index.  However, we allocate TLS in a lazy fashion,
    // so this test can fail unless we've already allocated the TLS segment.
    // So we force the allocation of the TLS index value by touching a TLS
    // value here.  So don't remove this silly call to AreOSExceptionsBlocked.
        CALL    AreOSExceptionsBlocked
{$ENDIF}
        MOV     EAX,Parameter
        MOV     ECX,[EAX].TThreadRec.Parameter
        MOV     EDX,[EAX].TThreadRec.Func
        PUSH    ECX
        PUSH    EDX
        CALL    _FreeMem
        POP     EDX
        POP     EAX
        CALL    EDX

{$IFNDEF PC_MAPPED_EXCEPTIONS}
        XOR     EDX,EDX
        POP     ECX
        MOV     FS:[EDX],ECX
        POP     ECX
{$ENDIF}
        POP     EBP
{$IFDEF PC_MAPPED_EXCEPTIONS}
        { Ditch our TOS marker }
        ADD     ESP, 4
{$ENDIF}
end;

  ThreadWrapper函数是使用BASM汇编代码实现,如果你熟悉BASM汇编,你就知道,前面的代码,是BASM汇编中函数传参数的约定,后面的才是重点,它内部实现了当执行线程函数出现异常错误时,转化为异常的机制。

  如果你直接使用CreateThread()创建线程,当然就不会有执行线程函数提供触发异常这样的好处,这才是使用BeginThread()函数替代CreateThread()的最重要原因,也是根本原因。

  线程中的异常机制很重要吗?当然重要!因为线程函数只是一个执行函数过程体,当在这个函数的执行过程中,如果发生异常,程序就会退出当前线程函数,也就是线程会终止。所以在线程中提供异常机制,并让我们在线程中可以捕获处理,是非常至关重要的。

http://blog.csdn.net/zang141588761/article/details/51654748

在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)的更多相关文章

  1. Delphi中实现MDI子窗体(转)

        Delphi中实现MDI子窗体 用MDI实现浏览子窗口,具有窗口管理功能,同屏观看多个网页的内容  ① 多文档窗体(MDI) MDI窗体是一种具有主子结构的窗体体系,微软的Word便是其中的一 ...

  2. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……

    接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...

  3. 转发 Delphi中线程类TThread 实现多线程编程

    Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchr ...

  4. Delphi中的线程类 - TThread详解

    Delphi中的线程类 - TThread详解 2011年06月27日 星期一 20:28 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本 ...

  5. Delphi CreateProcess 创建一个新的进程和它的主线程

    Delphi CreateProcess WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件 CreateProcess百科名片 WIN32 ...

  6. Delphi中的线程类(转)

    Delphi中的线程类 (转) Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对 TThread类的几个成员作一简单介绍,再说明一下 ...

  7. Delphi中线程类TThread实现多线程编程1---构造、析构……

    参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...

  8. Delphi中DLL的创建和使用

    参考:http://blog.csdn.net/ninetowns2008/article/details/6311663 结合这篇博客:http://www.cnblogs.com/xumenger ...

  9. Delphi中DLL的创建和使用(转)

    Delphi中DLL的创建和使用     1.DLL简介:   2.调用DLL:   3.创建DLL:   4.两个技巧:   5.初始化:   6.例外处理.            1.DLL简介  ...

随机推荐

  1. iOS中js与objective-c的简单交互

    1.首先是objective-c调用js中的代码,可以用UIWebview中的一个方法 stringByEvaluatingJavaScriptFromString:后面接的是js中的方法名.这个函数 ...

  2. iOS8.1 编译ffmpeg和集成第三方实现直播(监控类)

    iOS8.1 编译ffmpeg和集成第三方实现直播(监控类) http://www.mamicode.com/info-detail-476094.html 一,下载并在终端中运行脚本编译ffmpeg ...

  3. 【hdu 2376】Average distance

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=2376 [题意] 让你计算树上任意两点之间的距离的和. [题解] 算出每条边的两端有多少个节点设为n ...

  4. KMP算法具体解释(贴链接)

    ---------------------------------------------------------------------------------------------------- ...

  5. 查询系统状态 内存大小 cpu信息 设备负载情况

    1.1 查看内存状态 /proc/meminfo里面存放着内存的信息 查看内存命令(包括虚拟内存swap): free -h (低版本系统可能不支持-h) 或者 free -m (以mb单位显示) a ...

  6. 【22.48%】【codeforces 689D】Friends and Subsequences

    time limit per test2 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...

  7. QT5.5.1 为Qtcreator 编译的程序添加管理员权限

    QT版本:5.5.1 QT Creator QT Creator 编译出来的程默认是不带管理员权限的.有时是需要管理员权限. 第一步: 创建文件 uac.manifest 添加如下代码 <?xm ...

  8. andriod 实现新浪、QQ场地、朋友微信圈、微信朋友分享功能

    前言:在自己的学习过程中的一些操作,分享一些理解. 下面将说明什么: 下载链接:http://download.csdn.net/detail/u014608640/7490357 首先.我们须要去S ...

  9. DOM渲染

    浏览器通常要求DOM 实现和JavaScript 实现保持相互独立.例如,在Internet Explorer 中,被称为JScript的JavaScript 实现位于库文件jscript.dll 中 ...

  10. WPF 窗体基类实现的体验及实现回车到下一控件

    原文:WPF 窗体基类实现的体验及实现回车到下一控件 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/jsyhello/article/details ...