• 浅谈线程


     

    由于工作中经常跟线程打交道,所以就谈谈自己对线程的一些理解。说到线程就不得不先说进程,进程通常被定义为一个正在运行的程序的实例。进程是一个正在运行的程序,它拥有自己的虚拟地址空间,拥有自己的代码、数据和其他系统资源,如进程创建的文件、管道、同步对象等,一个进程也包含了一个或者多个运行在此进程内的线程。

    那进程和程序又有什么区别了?虽然程序和进程在表面上很相似,但是它们有者根本的区别。程序是一连串静态的指令,而进程是一个容器,它包含了一系列运行在这个程序实例上下文中的线程使用的资源。

    操作系统通过CreateProcess创建进程或,会创建一个线程执行进行中的的代码(也就是主线程),主线程可以创建其他线程,这些线程叫辅助线程也叫工作线程。

    1.线程的创建

    线程的创建是通过函数CreateThread来实现的,

     HANDLE CreateThread(

     LPSECURITY_ATTRIBUTES lpThreadAttributes,    //线程的安全属性

     DWORD dwStackSize,                        //线程堆栈的大小

     LPTHREAD_START_ROUTINE lpStartAddress,     //线程函数的起始地址

     LPVOID lpParameter,                        //传递个线程函数的参数

     DWORD dwCreationFlags,                    //线程创建后是否立即启动

     LPDWORD lpThreadId                        //线程的ID

    );

    每个线程都要都要有个入口函数(也就是线程函数),

    下面是一个线程函数定义的例子:DWORD WINAPI ThreadProcLPVOID lpParam);

    WINAPI是个宏 #define WINAPI _stdcall;

    2.线程的内核对象

    线程内核对象就是一个数据结构,包含了线程的一些信息。当成功调用CreateThread后,系统都会在内部为新线程分配一个内核对象。

    内核对象的基本成员:

    Context

    Context也就是线程上下文,包括了一组CPU寄存器,反映了线程上次运行时CPU寄存器的状态。

    Usage Count

    Usage Count就是线程的使用计数。线程只要没有结束,Usage Count就至少为1。当这个值为0时,系统就认为已经没有任何进程在引用此内核对象了,于是线程内核对象就要从内存中撤销。在创建一个新的线程时,CreateThread函数返回内核对象的句柄,相当于打开一次新创建的内核对象,这会促使Usage Count1,所以创建一个新的线程后,Usage Count就是2。调用函数OpenThread会使Usage Count再次加1,而CloseHandle会使Usage Count1

    Suspend Count

    Suspend Count暂停次数。用ResumeThread函数可以唤醒一个线程,会减少Suspend Count,当Suspend Count0时线程被恢复运行。用SuspendThread函数挂起一个线程,这个函数会增加Suspend Count

    Exit Code

    Exit Code就是线程退出代码(也就是线程函数的返回值),当线程函数还没有执行完时,Exit Code的值就是STILL_ACTIVE

    Signaled

    Signaled指示线程对象是否为受信状态。线程运行时Signaled永远是False也就是未受信。只有线程结束后才是受信状态。

    3.线程的优先级

    首先得说下Windows调度线程的原则:只有优先级最高的线程是可调度的,操作系统就不会将CPU分配给优先级低的。但是有些方法会使线程暂停或者不可调度,如WaitForSingleObject或者GetMessage,这样优先级低的就可以分配到CPU的时间片,一旦优先级高的线程被唤醒了,优先级低的线程将被阻塞。Windows支持6个优先级类:idlebelow normalnormalabove normalhighreal-time

    4.线程的终止

    终止线程有4种方法:

    1.       使用ExitThread函数终止线程

    采用这种方法终止线程,会使系统释放掉此线程使用的所有资源但是c/c++资源却不能得到正确的清除。

    2.       使用TerminateThread函数在一个线程中强制终止另一个线程的执行

    使用TerminateThread函数终止线程,系统不会释放线程使用的堆栈,所以除非迫不得已,尽量避免使用这个函数终止线程。

    3.       使用ExitProcess函数结束进程

    使用这个方法相当与对进程中的每个线程使用TerminateThread函数。

    4.       线程函数自然退出

    这种方法是最好的,线程函数返回时Windows将终止线程的执行。

    函数说明:

    Handle OpenThread(

             DWORD dwDesiredAccess//想要访问的权限

             BOOL bInheritHandle,     //此函数返回的句柄是否可以被子进程继承

             DWORD deThreadId           //目标线程的ID

    )

    Void ExitThread(DWORD dwExitCode);//dwExitCode线程的退出代码

    BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);//hThread目标线程句柄

  • 相关阅读:
    【转】我该 不该学习VULKAN
    游戏开发内功秘籍记录
    VS 配置外部DLL的引用路径【可执行文件的环境路径】
    OpenGL3.x,4.x中使用FreeImage显示图片的BUG-黑色,或颜色分量顺序错乱
    C++风格与C风格文件读写效率测试-vs2015,vs2017
    【转】矩阵的几何解释
    android 线程间通信
    android 网络
    安卓 碎片 如何实现类似 活动 栈的 进栈 出栈
    安卓 内容提供者 观察者 解析器
  • 原文地址:https://www.cnblogs.com/ssqjd/p/1400250.html
Copyright © 2020-2023  润新知