zoukankan      html  css  js  c++  java
  • 浅谈线程

     

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

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

    操作系统通过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目标线程句柄

  • 相关阅读:
    复利结对项目 增添
    结对编程-对队友的评价
    复利结对项目
    阅读《构造之法》第4章有感
    单元测试
    实验一 命令解释程序cmd的编写
    阅读《构造之法》1、2、3章有感
    复利计算
    实验总结
    汉堡包评价
  • 原文地址:https://www.cnblogs.com/ssqjd/p/1400250.html
Copyright © 2011-2022 走看看