zoukankan      html  css  js  c++  java
  • Windows线程基础

    线程由两部分组成:线程内核对象和线程栈。关于内核对象请看windows内核对象简介

    线程内核对象,操作系统用线程内核对象来管理线程,操作系统还用它来存放统计信息。

    线程栈,用于维护线程执行时所需的所有函数参数和局部变量,就是C#程序员常说的线程栈和托管堆中的线程栈。

    我们知道进程是有惰性的,它的所有工作都是由线程完成的,而进程只是为线程提供场地,线程函数执行我们让它执行的任务,最终线程函数将终止运行并返回,线程将终止运行,线程的内存将被释放,线程内核对象的使用计数将减一,如果线程内核对象的使用计数减为0,线程内核对象将被销毁。

    说了这么多,感觉有点虚,我们还是来看看创建线程的函数吧。

    CreateThread(

        LPSECURITY_ATTRIBUTES lpThreadAttributes,

        SIZE_T dwStackSize,

        LPTHREAD_START_ROUTINE lpStartAddress,

        LPVOID lpParameter,

        DWORD dwCreationFlags,

        PDWORD lpThreadId

    );

    lpThreadAttributes:用于设置线程的安全性,线程内核对象是否可以被进程的子进程所继承,详细了解我的这篇文章windows内核对象简介

    dwStackSize:用于设置线程栈的大小,默认为1MB

    lpStartAddress:线程所执行的函数的地址

    lpParameter:线程函数的参数

    dwCreationFlags:用于标识线程是否马上执行

    lpThreadId:线程ID

    创建线程。调用CreateThread时,系统会创建一个线程内核对象,这个内核对象由操作系统管理,当它的使用计数为0时,会被自动销毁。而当前进程的句柄表也会有一项用于纪录线程内核对象,表示对它的一个引用,同时系统会在进程的地址空间中分配一块内存共线程栈使用。新线程可以访问进程句柄表中的所有内核对象,内核对象由系统内核管理,而进程句柄表维护该进程所用到的内核对象的引用,而线程则通过句柄表中内核对象的地址引用内核对象。新线程还可以访问进程的所有内存以及进程中所有线程的栈,如子线程可以很方便的访问主线程的栈。还有一点需要说明的就是,线程内核对象创建完成之后,线程并不会马上执行,因为线程栈的内存分配和初始化时要时间的,等一切就绪后进程才会开始执行。

    终止线程。最好让线程函数自动返回,而不应该强制终止线程函数,因为线程函数在返回前还要做些清理工作,如析构对象,回收内存,让操作系统正确释放线程栈使用的内存,如果强制终止关闭线程,可能这些工作就不能正确的执行,很可能就会出现内存泄露。

    线程内幕。对CreateThread的调用产生一个线程内核对象,内核对象的使用计数为2,个人认为使用计数为2的原因是:当前进程对它的引用,还有就是保证在线程函数返回是内核对象不用马上自动销毁,因为当前函数返回时内核对象的使用计数肯定要减一,当减为0时内核对象将自动销毁。还要初始化内核对象的其他属性,并将内核对象设为未触发状态,使其随时可以被执行。等内核对象和线程栈内存一切就绪,系统就会将两个值写入新线程栈的最上端,一个是线程函数的参数,一个是线程函数的地址。

    每个线程都有自己的一组CPU寄存器,即为线程的上下文。上下文反映了当前线程执行一次时线程CPU寄存器的状态。因为一个线程可能要经过多次的CPU轮询,才能执行完成,在每次CPU时间用完之前保存CPU寄存器的状态,好让下次轮询到达时继续执行。线程CPU寄存器全部都保存在一个CONTEXT结构中,而CONTEXT本身保存在线程内核对象中。指令指针寄存器和栈指针寄存器是线程上下文中两个重要的寄存器,线程始终在线程的上下文中运行,当线程的内核对象被初始化时,CONTEXT结构的堆栈指针寄存器被设为函数在线程栈中的地址,而指令指针寄存器被设为RtlUserThreadStart函数的地址,而函数RtlUserThreadStart则是线程开始的地方。

    最后想说的是,建议用_beginthreadex代替CreateThread创建函数。

    作者:陈太汉

    博客:http://www.cnblogs.com/hlxs/

  • 相关阅读:
    lr 增强窗格中,如何生成调试信息?
    lr 自带的例子,如何进行关联,通过代码的函数进行实现
    lr11 录制脚本时候,无法自动启动ie,查了网上很多方法都未解决?
    loadrunner11 录制脚步不成功,在录制概要出现“No Events were detected”,浮动窗口总是显示“0 Events”,解决办法
    loadrunner11 安装及破解教程来自百度文库
    安装loadrunner11 ,出现如下错误如何解决?
    回收站数据删除了,如何进行恢复?
    网管工作方面——————打印机删除了然后开机重启他依然存在,如何解决
    Windows 不能在 本地计算机 启动 SQL Server 服务 错误代码126
    Sorry, the page you are looking for is currently unavailable. Please try again later. Nginx
  • 原文地址:https://www.cnblogs.com/hlxs/p/2820992.html
Copyright © 2011-2022 走看看