<small id='HqYp'></small> <noframes id='ZjYqw'>

  • <tfoot id='tHZcRQ'></tfoot>

      <legend id='BmYDLl'><style id='IoUhkPLd'><dir id='moTFG'><q id='iBJOoZH'></q></dir></style></legend>
      <i id='5voNM7SX'><tr id='b4eRnGNq5'><dt id='OZ9vmP'><q id='18qB5k'><span id='YrOJ'><b id='HoPe0EYui6'><form id='M2Gx6JOf'><ins id='gtSq1'></ins><ul id='NeYO21oRax'></ul><sub id='Ik3hzU9'></sub></form><legend id='vTFjDkU'></legend><bdo id='f25H'><pre id='5FpYV'><center id='XOjFN0ctEz'></center></pre></bdo></b><th id='nIuB46qop'></th></span></q></dt></tr></i><div id='8fKl6k'><tfoot id='Dmgt0'></tfoot><dl id='7oNCa3Q2n8'><fieldset id='va6HPbKjeB'></fieldset></dl></div>

          <bdo id='GQvFl'></bdo><ul id='kUQjN'></ul>

          1. <li id='NIW0C56ei'></li>
            登陆

            C++系列 --- 线程内核目标

            admin 2019-11-01 139人围观 ,发现0个评论

            一、线程内核对象

            线程内核对象就是一个包含了线程状态信息的数据结构。每次对CreateThread函数的成功调用,系统都会在内部为新的线程分配一个内核对象。系统提供的管理线程的函数就是依靠访问线程内核对象来管理实现的。

            线程内核对象结构

            线程创建内核对象时,系统对它的各个成员进行初始化

            1> 线程上下文句柄

            每个线程都有自己的一组CPU寄存器,成为线程的上下文。这组寄存器的值保存在一个CONTEXT结构里,反映了该线程上次运行时CPU寄存器的状态。

            2> 使用技术Usage Count

            • 该成员记录线程内核对象的使用次数。使用技术初始状态为2,创建一个线程时,因为CreateThread函数返回了线程内核对象的句柄,相当于打开一次,就促使Usage Count值加1。如果调用OpenThread函数,会再加1。
            • 因此在使用完他们的句柄之后,一定要调用CloseHandle函数进行关闭。使Usage Count值减1.
            • 如果在刚创建线程时调用CloseHandle函数关闭CreateThread函数返回的句柄,Usage Count值减为1,但线程没有被终止。线程结束要关闭句柄,不然内存泄漏。

            3> 暂停次数 Suspend Count

            该成员用于指明线程的暂停计数。

            DWORD ResumeThread(HANDLE hThread); // 唤醒挂起线程

            DWORD SuspendThread(HANDLE hThread); // 挂起线程

            上面两个函数用于减少或增加Suspend Count。

            在相同优先级下,当Suspend Count变为0时,系统可以调度该线程。

            4> 退出代码 Exit Code

            Exit Code指定线程的退出代码,也可以说是线程函数的返回值。在线程运行期间,线程函数没有返回,值为STILL_ACTIVE。当线程结束后,系统自动将ExitCode设为线程函数的返回值。可以用GetExitCodeThread函数得到线程的退出代码。

            5> 是否受信 Signaled

            Signaled指示了线程对象是否为受信状态。运行期间FALSE,即未受C++系列 --- 线程内核目标信,线程结束后,系统将其置为TRUE,针对此对象的等待函数(如WaitForSingleObjecC++系列 --- 线程内核目标C++系列 --- 线程内核目标t)就会返回。

            二、线程的终止

            线程正常终止时,会发生以下时间:

            在线程函数中创建的所有C++对象将通过他们各自的稚童的笑颜析构函数被正确的销毁。

            该线程使用的堆栈被释放。

            系统将线程内核对象中的ExitCode的值由STILL_ACTIVE设置为线程函数返回的值。

            系统将递减线程内核对象中Usage Count的值。

            线程终止的四种方法

            1、线程函数自然退出。

            2、使用ExitThread函数来终止线程。

            3、使用TeriminateThread函数在一个线程中强制终止另一个线程的运行。

            3、使用ExitProcess函数结束进程。

            线程自然退出这种情况时最安全的,但是其他三种方式会存在一个问题,ExitThread、TeriminateThread、ExitProcess为C风格的Win32函数,不会调用C++的运行时,即在释放资源的时候,析构函数不会被执行,具体实例如下:

            示C++系列 --- 线程内核目标例

            #include 
            #include
            using namespace std;

            class CMyObj
            {
            public:
            CMyObj()
            {
            printf("构造函数!\n");
            }
            ~CMyObj()
            {
            printf("析构函数!\n");
            }
            };

            int main()
            {
            CMyObj obj;

            system("pause");
            return 0;
            }

            正常运行结果

            在main函数中添加ExitThread()函数,则会出现问题,即析构函数不会被C++系列 --- 线程内核目标执行!

            请关注微信公众号
            微信二维码
            不容错过
            Powered By Z-BlogPHP