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

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

在 Windows 上建立一个线程, 离不开 CreateThread 函数;

TThread.Create 就是先调用了 BeginThread (Delphi 自定义的), BeginThread 又调用的 CreateThread.

既然有建立, 就该有释放, CreateThread 对应的释放函数是: ExitThread, 譬如下面代码:

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

代码注释:

当前程序是一个进程, 进程只是一个工作环境, 线程是工作者;

每个进程都会有一个启动线程(或叫主线程), 也就是说: 我们之前大量的编码都是写给这个主线程的;

上面的 ExitThread(0); 就是退出这个主线程;

系统不允许一个没有线程的进程存在, 所以程序就退出了.

另外: ExitThread 函数的参数是一个退出码, 这个退出码是给之后的其他函数用的, 这里随便给个无符号整数即可.

或许你会说: 这个 ExitThread 挺好用的; 其实不管是用 API 还是用 TThread 类写多线程, 我们很少用到它; 因为:

1、假如直接使用 API 的 CreateThread, 它执行完入口函数后会自动退出, 无需 ExitThread;

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

除了 CreateThread, 还有一个 CreateRemoteThread, 可在其他进程中建立线程, 这不应该是现在学习的重点;

现在先集中精力把 CreateThread 的参数搞彻底.

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

"句柄" 类似指针, 但通过指针可读写对象, 通过句柄只是使用对象;

有句柄的对象一般都是系统级别的对象(或叫内核对象); 之所以给我们的是句柄而不是指针, 目的只有一个: "安全";

貌似通过句柄能做很多事情, 但一般把句柄提交到某个函数(一般是系统函数)后, 我们也就到此为止很难了解更多了; 事实上是系统并不相信我们.

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

时间: 2024-10-21 18:47:13

多线程编程(2)-从CreateThread说起的相关文章

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

function CreateThread( lpThreadAttributes: Pointer; {安全设置} dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD ): THandle; stdcall; CreateThread 的第一个参数 lpThreadAttributes 是指向

多线程编程(6)-从 CreateThread 说起[续四]

function CreateThread( lpThreadAttributes: Pointer; dwStackSize: DWORD; {堆栈大小} lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD ): THandle; stdcall; CreateThread 的第二个参数是分配给线程的堆栈大小. 这首先这可以让我们知道

多线程编程(5)-从CreateThread说起[续三]

function CreateThread( lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; {入口函数的指针} lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD ): THandle; stdcall; 到了入口函数了, 学到这个地方, 我查了一个入口函数的标准定义, 这个函数的标准

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

function CreateThread( lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; {入口函数的参数} dwCreationFlags: DWORD; var lpThreadId: DWORD ): THandle; stdcall; 线程入口函数的参数是个无类型指针(Pointer), 用它可以指定任何数据; 本

多线程编程(3)-从CreateThread说起[续]

function CreateThread( lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; {启动选项} var lpThreadId: DWORD ): THandle; stdcall; CreateThread 的倒数第二个参数 dwCreationFlags(启动选项)

汇编教程之多线程编程

本课中,我们将学习如何进行多线程编程.另外我们还将学习如何在不同的线程间进行通信. 理论: 前一课中,我们学习了进程,其中讲到每一个进程至少要有一个主线程.这个线程其实是进程执行的一条线索,除此主线程外您还可以给进程增加其它的线程,也即增加其它的执行线索,由此在某种程度上可以看成是给一个应用程序增加了多任务功能.当程序运行后,您可以根据各种条件挂起或运行这些线程,尤其在多CPU的环境中,这些线程是并发运行的.这些是在W32下才有的概念,在WIN16下并没有等同的概念. 在同一进程中运行不同的线程

事件对象在多线程编程中的应用

本课中我们将要学习事件对象以及如何在多线程编程中如何使用同步对象. 理论:上一课中我们演示了如何用WINDOWS消息在不同的线程之间进行通讯.另外的两种,即:使用全局变量和事件对象,将在本课中讲解. 事件对象就像一个开关:它只有两种状态---开和关.当一个事件处于"开"状态,我们称其为"有信号"否则称为"无信号".您可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是"无信号"就让该线程睡眠,这样该线程占用的C

多线程编程之二——MFC中的多线程开发

五.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等.用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等.但对于Win32的API编程而言,这两种线程是没有区别的,它们都只需线程的启动地址即可启动线程来执行任务. 在MFC中,一般用全局函数Afx

Linux的多线程编程的高效开发经验

简介:本文中我们针对 Linux 上多线程编程的主要特性总结出 5 条经验, 用以改善 Linux 多线程编程的习惯和避免其中的开发陷阱.在本文中,我们穿 插一些 Windows 的编程用例用以对比 Linux 特性,以加深读者印象. 背景 Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会 导致程序问题不穷,死锁不断.本文中我们从 5 个方面总结出 Linux 多线程编 程上的问题,