Windows学习(008)--线程(一)

线程函数

HANDLE WINAPI CreateThread(
  _In_opt_  LPSECURITY_ATTRIBUTES  lpThreadAttributes, //线程安全结构体,一般设置为NULL
  _In_      SIZE_T                 dwStackSize,        //线程分配堆栈的大小,填0编译器会设置默认大小
  _In_      LPTHREAD_START_ROUTINE lpStartAddress,     //线程回调函数地址
  _In_opt_  LPVOID                 lpParameter,        //回调函数参数
  _In_      DWORD                  dwCreationFlags,    //控制线程创建的标志
  _Out_opt_ LPDWORD                lpThreadId          //线程ID
);

详情参照MSDN

线程堆栈

  1. 当需要创建一个线程时,必须在一个线程中使用CreatrThread这个函数,来进行一个线程的创建
  2. 在进行线程创建的同时,会创建一个线程内核对象,其和进程内核对象相似,它只是一个结构体,它并不代表线程本身,这个结构体主要用来操作系统对我们的线程进行管理
  3. 它会分配一块空间,这块空间属于当前进程内的一块空间,然后会将当前这空间做为这个线程的堆栈,这就意味着每个线程都自己各自的堆栈

线程入口函数

DWORD WINAPI ThreadProc(
  _In_ LPVOID lpParameter
);

主线程退出和其它线程退出区别

  • 主线程退出,就意味着整个进程消亡,进程所占的内存空间被释放,其它线程在本进程中,自然其它线程的堆栈空间被释放,因而有主线程退出,其它线程也被迫退出
  • 其它线程退出,只是该线程堆栈被释放,不影响其它线程,所以也不影响主线程

线程间参数传递

现在有这样一个情景

在一个进程中,有线程A,A创建了一个线程B,并把A中一个栈上的一个变量C作为参数传入B.现在如果在B中使用这个参数会有2种情况:
1. A在B使用C前,还没有退出了,那么B使用C就没有问题
2. A在B使用C前,已经退出了,A的栈已经被释放了,则C也被释放了,那么B使用C,C现在已经是不存在了,那么在就会出现问题了

为了避免出现这种现象发生,我们可以在A中调用一个阻塞函数,比如WaitForSingleObject,来等待B线程的退出,这样就可以保证变量C在B线程中使用时是存在的.或者,可以在堆上new出一个变量C,给到B,这样就算A提前消亡,也不会影响C的生命周期,B也能正常使用C

时间片

指CUP分配给线程的时间,这个时间是极短的, 在该时间内,线程所做的事情是有限的.一旦当此时间结束,此线程就会挂机,时间片被分配给其它线程.在单核的情况下,所有的线程以轮询的方式在运行,但这个轮询时间极快,甚至可忽略,所以有微观串行,宏观并行.

线程销毁

  1. 先回顾一下进程在销毁的时候要做哪些事情:

    1. 销毁临时对象
    2. 释放堆栈
    3. 将返回值设置为我的退出代码
    4. 减少进程的内核对象的引用计数

    实际上这也是线程在销毁时候要做的事情:

    1. 销毁临时对象,调用我们的析构函数
    2. 释放线程里面的所分配的堆栈 窗口 Hook
    3. 线程的入口函数的返回值设置为我们的退出代码
    4. 减少线程内核对象的使用计数

    从现在来看,进程真的是惰性的,进程的退出也是线程退出来具体来做的事情,我们的进程退出,实际上是主线程退出.

  2. 结束线程的函数

    //立即结束当前线程
    VOID WINAPI ExitThread(
      _In_ DWORD dwExitCode
    );
    
    //可以结束其它的线程
    BOOL WINAPI TerminateThread(
      _Inout_ HANDLE hThread,
      _In_    DWORD  dwExitCode
    );
    

    当我们使用某亿线程中使用ExitThread,它会终止我们这个线程的运行,然后它会将属于当前线程的栈销毁,但是不会去调用析构函数,此时会造成内存泄漏.

线程启动

  1. 内核对象结构体
    - 使用计数
    - ExitCode
    - Signaled 当这个线程为有信号的时候CPU会去执行他,无信号的时候CPU就不会去执行它
  2. CONTEXT 线程上下文 存储了CPU寄存器的状态 IP(指令) SP(栈寄存器)
  3. 线程去进程当中申请一片内存,作为当前线程的栈
  4. 传递2个参数,lParam, lpStartAddress,当前线程的入口函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值