1. function CreateThread(
  2. lpThreadAttributes: Pointer;           {安全设置}
  3. dwStackSize: DWORD;                    {堆栈大小}
  4. lpStartAddress: TFNThreadStartRoutine; {入口函数}
  5. lpParameter: Pointer;                  {函数参数}
  6. dwCreationFlags: DWORD;                {启动选项}
  7. var lpThreadId: DWORD                  {输出线程 ID }
  8. ): THandle; stdcall;                     {返回线程句柄}

--------------------------------------------------------------------------------
 
在 Windows 上建立一个线程, 离不开 CreateThread 函数;
 TThread.Create 就是先调用了 BeginThread (Delphi 自定义的), BeginThread 又调用的 CreateThread.
 既然有建立, 就该有释放, CreateThread 对应的释放函数是: ExitThread, 譬如下面代码:
--------------------------------------------------------------------------------

  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3. ExitThread(0); {此句即可退出当前程序, 但不建议这样使用}
  4. end;

--------------------------------------------------------------------------------
 
代码注释: 
当前程序是一个进程, 进程只是一个工作环境, 线程是工作者;
 每个进程都会有一个启动线程(或叫主线程), 也就是说: 我们之前大量的编码都是写给这个主线程的;
 上面的 ExitThread(0); 就是退出这个主线程;
 系统不允许一个没有线程的进程存在, 所以程序就退出了.
 另外: ExitThread 函数的参数是一个退出码, 这个退出码是给之后的其他函数用的, 这里随便给个无符号整数即可.

或许你会说: 这个 ExitThread 挺好用的; 其实不管是用 API 还是用 TThread 类写多线程, 我们很少用到它; 因为:
 1、假如直接使用 API 的 CreateThread, 它执行完入口函数后会自动退出, 无需 ExitThread;
 2、用 TThread 类建立的线程又绝不能使用 ExitThread 退出; 因为使用 TThread 建立线程时会同时分配更多资源(譬如你自定义的成员、还有它的祖先类(TObject)分配的资源等等), 如果用 ExitThread 给草草退出了, 这些资源将得不到释放而导致内存泄露. 尽管 Delphi 提供了 EndThread(其内部调用 ExitThread), 这也不需要我们手动操作(假如非要手动操作也是件很麻烦的事情, 因为很多时候你不知道线程是什么时候执行完毕的).

--------------------------------------------------------------------------------

除了 CreateThread, 还有一个 CreateRemoteThread, 可在其他进程中建立线程, 这不应该是现在学习的重点;
 现在先集中精力把 CreateThread 的参数搞彻底.

倒着来吧, 先谈谈 CreateThread 将要返回的 "线程句柄".

"句柄" 类似指针, 但通过指针可读写对象, 通过句柄只是使用对象;
 有句柄的对象一般都是系统级别的对象(或叫内核对象); 之所以给我们的是句柄而不是指针, 目的只有一个: "安全"; 
貌似通过句柄能做很多事情, 但一般把句柄提交到某个函数(一般是系统函数)后, 我们也就到此为止很难了解更多了; 事实上是系统并不相信我们.

不管是指针还是句柄, 都不过是内存中的一小块数据(一般用结构描述), 微软并没有公开句柄的结构细节, 猜一下它应该包括: 真实的指针地址、访问权限设置、引用计数等等.

既然 CreateThread 可以返回一个句柄, 说明线程属于 "内核对象".
 实际上不管线程属于哪个进程, 它们在系统的怀抱中是平等的; 在优先级(后面详谈)相同的情况下, 系统会在相同的时间间隔内来运行一下每个线程, 不过这个间隔很小很小, 以至于让我们误以为程序是在不间断地运行.

这时你应该有一个疑问: 系统在去执行其他线程的时候, 是怎么记住前一个线程的数据状态的?
 有这样一个结构 TContext, 它基本上是一个 CPU 寄存器的集合, 线程是数据就是通过这个结构切换的, 我们也可以通过 GetThreadContext 函数读取寄存器看看.

附上这个结构 TContext(或叫: CONTEXT、_CONTEXT) 的定义:
--------------------------------------------------------------------------------

  1. PContext = ^TContext;
  2. _CONTEXT = record
  3. ContextFlags: DWORD;
  4. Dr0: DWORD;
  5. Dr1: DWORD;
  6. Dr2: DWORD;
  7. Dr3: DWORD;
  8. Dr6: DWORD;
  9. Dr7: DWORD;
  10. FloatSave: TFloatingSaveArea;
  11. SegGs: DWORD;
  12. SegFs: DWORD;
  13. SegEs: DWORD;
  14. SegDs: DWORD;
  15. Edi: DWORD;
  16. Esi: DWORD;
  17. Ebx: DWORD;
  18. Edx: DWORD;
  19. Ecx: DWORD;
  20. Eax: DWORD;
  21. Ebp: DWORD;
  22. Eip: DWORD;
  23. SegCs: DWORD;
  24. EFlags: DWORD;
  25. Esp: DWORD;
  26. SegSs: DWORD;
  27. end;

--------------------------------------------------------------------------------
 
CreateThread 的最后一个参数是 "线程的 ID";
 既然可以返回句柄, 为什么还要输出这个 ID? 现在我知道的是:
 1、线程的 ID 是唯一的; 而句柄可能不只一个, 譬如可以用 GetCurrentThread 获取一个伪句柄、可以用 DuplicateHandle 复制一个句柄等等.
 2、ID 比句柄更轻便.

在主线程中 GetCurrentThreadId、MainThreadID、MainInstance 获取的都是主线程的 ID.

转自:http://www.cnblogs.com/del/archive/2009/02/10/1387559.html

http://blog.csdn.net/rznice/article/details/8245788

多线程编程 CreateThread(解释了TContext)的更多相关文章

  1. CreateThread简单那多线程编程

    CreateThread简单那多线程编程 作者:vpoet mail:vpoet_sir@163.com 在进行多任务处理的时候我们往往会用到多线程技术,多线程理论上是多个线程同事处理不同的工作,但是 ...

  2. QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )

    传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...

  3. windows多线程编程星球(一)

    以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分.原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这部分内容主要出现在讲原理的操作系统书的某一章,看完原理是懂 ...

  4. [转]Delphi多线程编程入门(二)——通过调用API实现多线程

    以下是一篇很值得看的关于Delphi多线程编程的文章,内容很全面,建议收藏. 一.入门 ㈠. function CreateThread(    lpThreadAttributes: Pointer ...

  5. VC++多线程编程

    一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX ...

  6. 多线程编程之二 ---MFC中的多线程开发

    下载源代码 五.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消 ...

  7. VC多线程编程

    一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX ...

  8. 《转》VC++多线程编程

    原地址:http://www.cnblogs.com/wxfasdic/archive/2010/09/23/1833522.html 留个纪念,不错的总结.十个例子清晰列举啦多线程编程的奥妙.  V ...

  9. VC++ 多线程编程,win32,MFC 例子(转)

    一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX ...

随机推荐

  1. 【Educational Codeforces Round 31 B】Japanese Crosswords Strike Back

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 所有数字的和加上n-1,如果为x则唯一,否则不唯一 [代码] #include <bits/stdc++.h> usin ...

  2. Access WMI via Python from Linux

    You can use Impacket (https://github.com/CoreSecurity/impacket) that has WMI implemented in Python. ...

  3. POJ 2886 Who Gets the Most Candies?(线段树&#183;约瑟夫环)

    题意  n个人顺时针围成一圈玩约瑟夫游戏  每一个人手上有一个数val[i]   開始第k个人出队  若val[k] < 0 下一个出队的为在剩余的人中向右数 -val[k]个人   val[k ...

  4. Centos 6 DNS Server 配置

    安装bind yum install -y bind bind-chroot bind-utis 如果是Centos 5 # yum -y install bind caching-nameserve ...

  5. 6.5 Android硬件访问服务使用反射

    1.前面的例子中App为了能够范问ILedService接口,把classes.jar导入到应用程序中,但是我们不想把classes编进apk包里面去,这样导致我们的apk程序会很大(解压缩apk会发 ...

  6. ARM 授权费用太贵 科技巨头欲转向开源架构 RISC-V

    不久前,特斯拉加入 RISC-V 基金会,并考虑在新款芯片中使用免费的 RISC-V 设计.至此,已有 IBM.NXP.西部数据.英伟达.高通.三星.谷歌.华为等 100 多家科技公司加入 RISC- ...

  7. Chinese remainder theorem

    https://en.wikipedia.org/wiki/Chinese_remainder_theorem http://planetmath.org/ChineseRemainderTheore ...

  8. JSP自己定义标签

    JSP自己定义标签 API文档: http://docs.oracle.com/javaee/7/api/ watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ ...

  9. [CSS] Conditionally Apply Styles Using Feature Queries @supports

    While browsers do a great job of ignoring styles they don’t understand, it can be useful to provide ...

  10. Java虚拟机解析篇之---内存模型

    今天闲来无事来,看一下Java中的内存模型和垃圾回收机制的原理.关于这个方面的知识,网上已经有非常多现成的资料能够供我们參考,可是知识还是比較杂的,在这部分知识点中有一本书不得不推荐:<深入理解 ...