windows 线程核心内容
线程 |
线程由2部分组成:线程的内核对象(存放线程统计信息)和 线程栈(维护线程执行所需的所有函数参数和局部变量) |
假如一个进程由2个以上的线程运行,这些线程共享同一地址空间,共享内核对象句柄(因为句柄表是针对每一个进程的) |
新线程与负责创建的那个线程在相同的进程上下文中运行,因此新线程可以访问进程内核对象的所有句柄,进程的所有内存以及同一进程中其他所有线程的栈。多个线程可以同时访问静态变量和全局变量。 |
createthread 预定空间的大小要么由stack链接器开关指定,可见于项目属性配置中。要么由cbstacksize的值指定,取较大值的那个。默认是1M大小。去进一步了解因线程栈大小引起的问题,涉及到线程栈异常及其捕获。 |
createthread 函数讲解 1.psa 一般设置为null ,表示使用默认的安全属性。 2.cbstackszie 默认一般是1M,在这里写0就是表示这意思。 3.pfnstartaddr 线程函数地址 4.pvparam 把该参数传给线程函数,该参数可以是数值或结构 5.dwcreateflags 可以是0(表示创建之后立即调度) 可以是create_suspended 表示挂起暂停线程。 6.pdwthreadid :线程id |
终止线程的办法 |
1.线程函数返回 |
2.调用exitthread杀死自己:操作系统清理该线程使用的所有操作系统资源,但c++资源(如c++类对象)不会被销毁 |
3.terminatethread随便一个线程,是异步函数。 4.进程终止运行,如调用exitprocess 或 terminatethread 函数 |
线程终止 |
1.线程拥有的用户对象(窗口和挂钩)句柄会被释放。 |
2.线程内核对象状态变成触发状态。进程初始化时为未触发状态,进程终止时自动变已触发状态。 |
3.线程内核对象的使用计数递减1 |
相对于createthread 更应用_beginthreadex ,相对于_endthreadex更应用_endthreadex。 |
线程的挂起和恢复 |
挂起(suspendthread):线程内核对象有一个挂起技术,并初始化为1.目的在于线程初始化需要时间,不想在线程还没有准备好就开始了。当CREATE_SUSPENDED标志时,线程出于挂起,如果没有,线程计数挂起递减为0.出于挂起状态的线程,可以改变它的环境变量(如优先级)。一个线程可以挂起多次,但也需要相同恢复的次数。任何线程都可以挂起另外一个线程,包括挂起自己。异步过程。 |
恢复(resumethread):一个线程多次调用suspendthread挂起,就必须相应调用多次resumethread恢复。线程不能自己恢复自己。 |
对应地,没有进程的直接挂起(suspendprocess)和恢复函数,只能通过遍历进程的所有线程,并挂起线程。 |
线程执行时间 (windows不是实时操作系统)所以sleep 函数精度也是在15ms左右 |
1.gettickcount 或者 gettickcount64 精度15ms左右 |
2.getthreadtimes |
3.queryperformancefrequency 和 queryperformancecounter 高精度 |
线程优先级:setthreadpriority,有0-31的优先级数。Getthreadpriority |
有7个优先级:time-critical、highest、above normal、nomal、below normal、lowest、idle |
判断线程是否结束的方法 1.GetExitCodeThread 比较原始的方法了,调用 GetExitCodeThread,如果返回STILL_ACTIVE,那就是还在运行,否则,会返回退出代码. 2.WaitForSingleObject 等待线程的内核对象被激发,线程退出的时候该内核对象就会被激发了 该方法为阻塞函数,会一直堵塞直至线程退出. 线程之间的通信 1.全局变量,多个线程同时访问同一个共享资源.通常我们会在这个全局变量前加上volatile声明,以防编译器对此变量进行优化。 2.Message消息机制 注:使用这个方法时,目标线程必须已经有自己的消息队列。否则会返回ERROR_INVALID_THREAD_ID错误。可以用 3.使用事件量cevent。 线程同步: 1.临界区关键段 2.事件量 3.互斥量 4. |
用户模式下的线程同步:关键段(critical section),以原子方式进行操控,一般作为全局变量分配 |
initializecriticalsection、entercriticalsection、leavecriticalsection、deletecriticalsection |
如果两个线程调用entercriticalsection,一个线程获准访问资源,另一线程被切换到等待状态。 |
内核对象下的线程同步 内核对象的状态:要么触发状态,要么未触发状态。 |
进程内核对象在创建时处于未触发状态。当进程终止时,内核对象变成触发状态。线程也是一样的。 |
等待函数:使一个线程自愿进入等待状态,直到指定的内核对象被触发为止。如有waitforsingleobject和waitformutipleobject函数。 |
waitforsingleobject: 被触发,返回WAIT_OBJECT_0 ; 超时,返回WAIT_TIMEOUT; 失败,返回 WAIT_FAILED ,可用GetLastError。 |
waitformutipleobject:参数bwaitall决定是只要有任意一个被触发,还是全部被触发才行。 如果bwaitall 为false 时,只要有任意一个被触发,就返回,返回值为WAIT_OBJECT_0和WAIT_OBJECT_0 + dwcount -1 之间的任意一个值。 如果bwaitall 为true 时,成功时,返回值为WAIT_OBJECT_0 超时,返回WAIT_TIMEOUT; 失败,返回 WAIT_FAILED ,可用GetLastError。 事件 信号量 互斥量 事件 HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes,// 安全属性 BOOL bManualReset,// 复位方式 BOOL bInitialState,// 初始状态 LPCTSTR lpName // 对象名称 ); bManualReset true: 表示手动重置,事件被触发的时候,正在等待该事件的所有线程都变成可调度的状态。 之后必须用ResetEvent函数来手工将事件的状态复原到无信号状态 false:表示自动重置,只有一个正在等待该事件的线程会变成可调度的状态。 当一个线程等待到事件信号后系统会自动将事件状态复原为无信号状态。 互斥量 线程id:用来表示占用这个互斥量是哪个线程 递归计数:线程占用这个互斥量的次数,要是次数大于1的唯一办法是: 线程试图访问一个未触发的互斥量对象,如果发现调用互斥量的线程的线程id和互斥量记录的线程id一致,即使是该互斥量尚未触发 互斥量的规则 1.线程id=0,即互斥量不被任何线程占用,处于触发状态。 相当于false 2线程id不为0,便是有一个线程在占用,处于未触发状态。 相当于true HANDLE CreateMutex( LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针 BOOL bInitialOwner, // 初始化互斥对象的所有者 LPCTSTRlpName // 指向互斥对象名的指针 ); bInitialOwner true 表示互斥锁创建出来后被当前线程持有 对象的线程id等于调用线程的线程id. 递归次数变成1. 处于未触发状态。 false 表示互斥锁创建出来后不被当前线程持有 线程id和递归计数为0,互斥量处于触发状态 互斥量必须结合等待函数一起使用。 当等待函数发现互斥量处于触发状态(即线程id=0),之后变回变成这样 1.线程能够执行下去。 2.互斥量的线程id变就成调用线程的线程id. 3.互斥量的递归次数就变成1. 4.互斥量状态变成未触发状态。 当等待函数发现互斥量处于未触发状态(即线程id不为0, 初始化时第二个变量为true),线程进入等待状态。 如果发现调用互斥量的线程的线程id和互斥量记录的线程id一致,会发生以下 1.线程执行下去 2.互斥量的递归计数+1 releasemutex 释放互斥量,结果是互斥量的递归次数减1.如果递归次数变成0,函数就线程id设置为0,互斥量就变成触发状态了。 |
windows 线程核心内容相关推荐
- 怎样学操作系统?一文带你掌握核心内容
导读:这一篇聊操作系统.最近大家对"卡脖子"讨论很多,首当其冲是芯片,紧接着就是操作系统.操作系统,英文名Operating System,所以也常简称"OS" ...
- Windows 7核心图形架构细致分析
深度解读 - Windows 7核心图形架构细致分析 编辑:马志文 时间: 2009-12-29 连接:http://technet.microsoft.com/zh-cn/library/ee921 ...
- 【操作系统】操作系统知识点整理;C++ 实现线程池与windows 线程池的使用;
文章目录 体系结构 冯诺依曼 存储结构 cache常见的组织结构 cache命中 缓存一致性 硬中断.软中断 操作系统结构 内核 Linux宏内核 内存管理 虚拟内存 内存管理 - 分段 - 分页 - ...
- 《Windows via C/C++》学习笔记 —— Windows 线程池
线程池(thread pool),允许有多个线程同时存在,并发执行,并且这些线程受到统一管理. 在Windows Vista中,提供了全新的线程池机制,一般这些线程池中的线程的创建的销毁是由操作系统自 ...
- Windows线程同步机制的区别与比较及进程通信方法
原文:http://blog.csdn.net/eulb/article/details/2177500 多线程同步机制 (Windows) 线程的同步机制: 1. Event 用事件(Event ...
- 进程线程006 Windows线程切换-线程优先级
文章目录 内容回顾 调度链表 如何高效查找 如果没有就绪线程怎么办 内容回顾 之前我们已经了解过,有三种情况会导致线程切换: 当前线程主动调用API:API函数–>KiSwapThread–&g ...
- 9.Windows线程切换_TSS
SwapContext这个函数是Windows线程切换的核心,无论是主动切换还,是系统时钟导致的线程切换,最终都会调用这个函数. 在这个函数中除了切换堆栈以外,还做了很多其他的事情,了解这些细节对我们 ...
- IOCP加Windows线程池打造高伸缩性高性能的服务器应用
对于IOCP,搞Windows服务器编程的都不会陌生,它所表现出来的性能是其他各种WinSock模型难望其项背的.撰写本文的目的就是为让大家能够在深入理解IOCP的基础上,再来深入的挖掘Windows ...
- 重磅丨英伟达刚刚发布全球最大GPU:GTC2018黄仁勋演讲核心内容整理
文章来源:机器之心 在刚刚结束的 Keynote 演讲中,英伟达创始人兼首席执行官黄仁勋宣布了该公司在芯片.AI 平台.自动驾驶上的一系列新动作. 正如黄仁勋所说的,今天的发布会有关于:「Amazin ...
- CSS核心内容整理 - (中)
2019独角兽企业重金招聘Python工程师标准>>> 本文是CSS核心内容整理的第二篇,承接上一篇的内容继续对CSS的一些重要内容进行整理,推荐先看完这个系列的上一篇. 四. 页 ...
最新文章
- 简述移动端IM开发的那些坑:架构设计、通信协议和客户端
- 数据分析需求转型与商业模式重构
- 初识压缩感知 compressive sensing
- js 调用父窗口的方法
- 微服务的下一步,离不开服务网格
- 音视频技术开发周刊 | 237
- 《数据库SQL实战》从titles表获取按照title进行分组
- 把Autofac玩的和java Spring一样6
- C语言 time函数 开销,C语言: 函数调用的开销
- Linux内核设计与实现---虚拟文件系统
- Java设计模式-外观模式(Facade)
- 计算机二级vb常考知识点,计算机二级VB考试重点考点
- 不加密,DES加密 RSA加密图
- vc调用matlab引擎实时绘图,怎么在vc++里调用matlab绘制spline插值曲线
- java可不可以写挂_用Java怎么写呀???我怕是java要挂了,太艰难了
- python snap7开发手册_python-snap7开发笔记
- 网站访问量统计的重要指标
- 关于手机游戏市场的调研方案(终结版)
- 如何美化菜单界面java_用 Java 创建带图像的菜单来美化界面
- Vue学习day03(vscode)
热门文章
- YII2中ActiveDataProvider与GridView的配合使用
- 警惕那些产生负价值的开发者
- react.js 表单验证-登录框
- InnoDB Plugin 1.0.2 for MySQL 5.1.30 (GA) Released
- sessionStrorage + localStorage+ cookes
- 一个简单的Java Web项目
- linux禁用scp命令,Linux系统如何关闭scp和sftp命令
- Spring Boot Admin 2.3.1 发布,轻量的图形化监控工具
- Vue 自定义弹出框组件(类似淘宝选择规格)
- Codeigniter3学习笔记三(创建类库及使用原生类库)