首页 > 其他分享 >Thread

Thread

时间:2023-02-26 13:45:18浏览次数:30  
标签:函数 Thread CreateThread 句柄 参数 线程 ID

线程是进程中的一个实体,是被系统独立调度和分派的基本单位。一个进程可以拥有多个线程,但是一个线程必须有一个进程。

线程自己不拥有系统资源,只有运行所必须的一些数据结构,但它可以与同属于一个进程的其它线程共享进程所拥有的全部资源,同一个进程中的多个线程可以并发执行。

(一)CreateThread

1.说明

使用CreateThread函数创建线程

2.函数原型

WINBASEAPI HANDLE WINAPI CreateThread (
LPSECURITY_ATTRIBUTES lpThreadAttributes, 
SIZE_T dwStackSize, 
LPTHREAD_START_ROUTINE lpStartAddress, 
LPVOID lpParameter, 
DWORD dwCreationFlags, 
LPDWORD lpThreadId);

参数说明:

第一个参数 lpThreadAttributes 表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。

第二个参数 dwStackSize 表示线程栈空间大小。传入0表示使用默认大小(1MB)。

栈是私有的但堆是公用的

什么是堆栈? 其实堆是堆、栈是栈, 有时 "栈" 也被叫做 "堆栈".

"栈"(或叫堆栈)适合存取临时而轻便的变量, 主要用来储存局部变量

现在我们知道了线程有自己的 "栈", 并且在建立线程时可以分配栈的大小.

第三个参数 lpStartAddress 表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。

等线程退出后, 我们用 GetExitCodeThread 函数获取的退出码就是这个返回值!

如果线程没有退出, GetExitCodeThread 获取的退出码将是一个常量 STILL_ACTIVE (259); 这样我们就可以通过退出码来判断线程是否已退出.

第四个参数 lpParameter 是传给线程函数的参数。

线程入口函数的参数是个无类型指针(Pointer), 用它可以指定任何数据;

第五个参数 dwCreationFlags 指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。

ResumeThread 恢复线程的运行; SuspendThread 挂起线程.

这两个函数的参数都是线程句柄, 返回值是执行前的挂起计数.

第六个参数 lpThreadId 将返回线程的ID号,传入NULL表示不需要返回该线程ID号

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

返回值:

CreateThread的返回值是线程的句柄,失败的话就返回NULL

3.返回线程句柄

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

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

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

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

既然 CreateThread 可以返回一个句柄, 说明线程属于 "内核对象".

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

这时你应该有一个疑问: 系统在去执行其他线程的时候, 是怎么记住前一个线程的数据状态的?

有这样一个结构 TContext, 它基本上是一个 CPU 寄存器的集合, 线程是数据就是通过这个结构切换的, 我们也可以通过 GetThreadContext 函数读取寄存器看看.

4.代码示例

    // 创建对应的线程
    for (int i = 0; i < SysInfo.dwNumberOfProcessors; i++)
    {
        HANDLE hThread = CreateThread(NULL, 0, WorkThread, this, 0, NULL);
        CloseHandle(hThread);
    }

 

标签:函数,Thread,CreateThread,句柄,参数,线程,ID
From: https://www.cnblogs.com/imreW/p/17156552.html

相关文章