博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows的线程使用
阅读量:5011 次
发布时间:2019-06-12

本文共 2275 字,大约阅读时间需要 7 分钟。

Windows的线程使用

2019521

12:12

   

和Linux不同,Windows的线程在执行结束以后默认不需要进程中的函数来引导销毁,而是由操作系统来自动销毁内存空间。

   

内核对象

操作系统创建的资源(Resource)有很多种,进程,线程,文件,信号量,互斥量等。他们都有一个共同点,"都是由Windows操作系统创建并管理的资源"。

不同的资源类型在"管理"的方式上存在有差异。操作系统为了记录管理资源的相关信息,在其内部生成了数据块(结构体变量)。由于每种资源需要维护的信息不同,所以每种资源拥有的数据块格式也具有差异。这类数据称之位"内核对象"。

所以可以理解,"内核对象"就是Windows操作系统为了管理系统资源而创建的资源信息对象。

内核对象的所有者是内核(操作系统)。内核对象的创建、管理、销毁时机等工作都有操作系统来完成。

   

基于Windows的线程创建

现代操作系统都在系统级别上支持线程的运行。程序开始运行以后,调用main函数的主体是线程。main函数的运行基于线程来完成。进程承载线程的运行。

   

  • 非显式创建线程的程序(如select服务器端)可以描述符:单一线程模型的应用程序
  • 显示创建线程的程序可以描述为:多线程模型的应用程序

   

windows创建线程的函数

系统函数

#include <windows.h>

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes,

SIZE_T dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreateionFlags,

LPDWORD lpThreadID

);

->>成功时返回线程句柄,失败时返回NULL

   

lpThreadAttributes:线程安全相关信息,NULL为默认设置

dwStackSize:分配给线程的栈大小,传递0生成默认大小

lpStartAddress:线程的main函数

lpParameter:线程main函数的参数

dwCreationFlags:指定线程创建后的行为,传递0,线程创建后立即进入可执行状态

lpThreadld:用于保存线程ID的变量地址

   

标准函数

#include <process.h>

uintptr_t _beginthreadex(

void * security,

unsigned stack_size,

unsigned (* start_address)(void*),

void * arglist,

unsigned initflag,

unsigned * thrdaddr

);

->>成功时返回线程句柄,失败时返回0

   

如果线程需要使用C/C++标准函数,则需要通过使用_beginthreadex函数来创建线程。与CreateThread函数相比,参数意义及调用顺序都没有区别。只是数据类型有所差异,需要适量修改。

   

句柄、内核对象与ID间的关系:

  • 通过句柄区分内核对象
  • 内核对象拥有资源的相关信息(通过内核对象区分线程)
  • 线程ID用于区分操作系统创建的所有线程

   

内核对象的两种状态

资源类型不同,内核对象也含有不同的信息。其中,应用程序实现过程中需要特别关注的信息被赋予某种"状态(state)"。线程内核对象中需要重点关注线程是否已经终止。终止状态又称为"signaled状态",未终止状态称为"non-signaled状态"。

进程和线程的初始化状态时non-signaled状态。内核对象中带有一个boolean变量,其初始值为FALSE,当发生约定情况(进程/线程结束),该值变为TRUE,即为signaled状态。

   

验证signaled状态(线程结束)

#include <windows.h>

DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);

->>成功时返回时间信息,失败时返回WAIT_FAILED

hHandle:内核对象句柄

dwMilliseconds 毫秒为单位的等待时间,传递INFINITE阻塞

返回值:进入signaled状态返回WAIT_OBJECT_0,超时返回WAIT_TIMEOUT

   

该函数由于发生事件(signaled)返回时,有时会把相应内核对象再次变为non-signaled状态,具有这种特性的内核对象称为"auto-reset模式"的内核对象,而不会自动跳转的内核对象称为"manual-reset模式"的内核对象。

   

验证多个内核对象的signaled状态

#include <windows.h>

DWORD WaitForMUltipleObjects(

DWORD nCount, const HANDLE * lpHandles, BOLL bWaitAll,

DWORD dwMilliseconds);

->>成功时返回事件信息,失败时返回WAIT_FAILED

   

nCount:内核对象总数

lpHandles:内核对象句柄数组

bWaitAllTRUE,等待全部。FALSE,有一个就返回

dwMilliseconds:等待时间,毫秒为单位,传递INFINITE阻塞

转载于:https://www.cnblogs.com/freesfu/p/10911693.html

你可能感兴趣的文章
(译)yaml快速教程
查看>>
C:大数相加
查看>>
160. Intersection of Two Linked Lists
查看>>
人生苦短,我用python-- Day11
查看>>
JAVA Bean
查看>>
ehcache memcache redis 三大缓存男高音_转
查看>>
curd_3
查看>>
百度地图API示例之设置地图显示范围
查看>>
Java构造方法、重载及垃圾回收
查看>>
.Net Core AES加密解密
查看>>
Spring Quartz实现任务调度
查看>>
python | 桶排序、冒泡排序、选择排序、去重
查看>>
两个Html页面之间值得传递
查看>>
EasyUI datagrid 的多条件查询
查看>>
Mac升级bash到最新版本
查看>>
利用vagrant打包系统--制作自己的box
查看>>
美女与硬币问题
查看>>
计算几何算法概览 (转)
查看>>
Notepad++的ftp远程编辑功能
查看>>
数据库多对多关联表(Python&MySQL)
查看>>