第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ----初始化一个线程
使用线程的一个常见问题就是如何能够在一个线程开始运行之前,适当地将它初始化。初始化最常见的理由就是为了调整优先权。另一个理由是为了在SMP 系统中设定线程比较喜欢的 CPU。第10 章谈到 MFC 时我们会看到其他一些理由。
基本问题在于,你需要一个线程 handle,才能够调整线程的性质。但如果你以默认型式调用 CreateThread(),新线程会如脱缰野马一下子就起跑了,你根本来不及进行初始化设定操作。
解决之道就是 CreateThread() 的第5个参数,它允许你指定线程诞生时的属性。目前只定义有一种属性,就是 CREATE_SUSPENDED。这个属性告诉CreateThread() 说:产生一个新线程,传回其 handle,但不要马上开始执行之。
下面是一个例子:
HANDLE hThread;
DWORD threadId;
hThread = CreateThread(NULL,
0,
ThreadFunc,
0,
CREATE_SUSPENDED,
&threadId
);
SetThreadPriority(hThread, THREAD_PRIORITY_IDLE);
一旦线程设定妥当,你可以调用 ResumeThread() 开始执行:
DWORD ResumeThread(
HANDLE hThread
);
参数
hThread 欲被再次执行的线程。
返回值
如果函数成功,则传回线程的前一个挂起次数。如果失败,则传回0xFFFFFFFF。GetLastError() 可以获得更详细的信息。
挂起(suspending)一个线程
相对于 ResumeThread(),毫不令人惊讶地,有一个 SuspendThread() 函数。这个函数允许调用端指定一个线程睡眠(挂起)。直到又有人调用了 ResumeThread(),线程才会醒来。因此,睡眠中的线程不可能唤醒自己。这个函数的规格如下:
DWORD SuspendThread(
HANDLE hThread
);
参数
hThread 欲被挂起的线程。
返回值
如果函数成功,则传回线程目前的挂起次数。如果失败,则传回0xFFFFFFFF。GetLastError() 可以获得更详细的信息。
SuspendThread() 是另一个可能会潜在引发问题的函数。考虑一下这种情况:一个进程拥有三个线程A,B,C。线程C正在某个 critical section 内,而线程B正在等它出来。然后,线程A挂起了线程C。在这种情况下,线程C将永远不会离开 critical section,而线程B也就相当于进入了死锁状态。
SuspendThread() 的最大用途就是用来协助撰写调试器。调试器允许在程序员的控制之下,启动或停止任何一个线程。
提要
在这一章中你看到了“结束一个线程”的正确方法,你也看到了线程优先权的定义方式, 及其改变所带来的影响。最后你还看到了如何利用CREATE_SUSPENDED 来初始化一个线程—在它开始执行之前。
第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ----初始化一个线程的更多相关文章
- 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ---线程优先权(Thread priority)
有没有过这样的经验?你坐在你的车子里,目的地还在好几公里之遥,而时间已经很晚了.你拼命想告诉那些挡住你去路的人们,今天这个约会对你是多么多么重要,能不能请他们统统--呃--滚到马路外?很不幸,道路系统 ...
- 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ---干净的终止一个线程
干净的终止一个线程 我曾经在第2章产生一个后台线程,用以输出一张屏幕外的 bitmap 图.我们必须解决的一个最复杂的问题就是,如果用户企图结束程序,而这张bitmap 图尚未完成,怎么办?第2章的 ...
- 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ---简介
这一章描述如何初始化一个新线程,如何停止一个执行中的线程,以及如何了解并调整线程优先权. 读过这一章之后,你将有能力回答一个 Win32 多线程程序设计的最基本问题.你一定曾经在 Usenet ...
- 使用Condition Variables 实现一个线程安全队列
使用Condition Variables实现一个线程安全队列 测试机: i7-4800MQ .7GHz, logical core, physical core, 8G memory, 256GB ...
- 启动一个线程是用run()还是start()?
启动一个线程是用run()还是start()? 答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行.这并不意味着线程就会立即运行.run ...
- 线程池如何复用一个线程-- ThreadPoolExecutor的实现(未完)
任务是一组逻辑工作单元,而线程则是使任务异步执行的机制.在Java中,Runnable对象代表一个任务,Thread对象负责创建一个线程执行这个任务. 前提:1. 程序需要处理大量任务 2. 任务的执 ...
- 【Java面试题】26 多线程有几种实现方法?同步有几种实现方法? 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
问题一:多线程有几种实现方法?同步有几种实现方法? 多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 同步的实现方面有两种,分别是synchronized,wait与not ...
- Java 如何正确停止一个线程
自己在做实验性小项目的时候,发现自己遇到一个问题:如何控制线程的"死亡"? 首先,如何开启一个线程呢? 最简单的代码: public class Main { public sta ...
- java 多线程 线程组ThreadGroup;多线程的异常处理。interrupt批量停止组内线程;线程组异常处理
1,线程组定义: 线程组存在的意义,首要原因是安全.java默认创建的线程都是属于系统线程组,而同一个线程组的线程是可以相互修改对方的数据的.但如果在不同的线程组中,那么就不能"跨线程组&q ...
随机推荐
- MyBatis从入门到放弃七:二级缓存原理分析
前言 说起mybatis的一级缓存和二级缓存我特意问了几个身边的朋友他们平时会不会用,结果没有一个人平时业务场景中用. 好吧,那我暂且用来学习源码吧.一级缓存我个人认为也确实有些鸡肋,mybatis默 ...
- HTML <td> 标签的 colspan 属性
HTML <td> 标签的 colspan 属性 实例 表格单元横跨两列的表格: 浏览器支持 所以浏览器都支持 colspan 属性. 没有浏览器支持 colspan="0&qu ...
- python常用标准库
-------------------系统内建函数------------------- 1.字符串 str='这是一个字符串数据测试数据'对应 str[0]:获取str字符串中下标为 ...
- Json作为配置文件注意事项
错误描述 在一次开发中,使用了JSON数据作为配置文件,但反序列化时总是出错,开始还以为是转义字符的问题,因为存了一个绝对路径(D:\xx\xx.json),后来测试发现竟然发现是类嵌套的问题. 解决 ...
- ZXing生成条形码、二维码、带logo二维码
采用的是开源的ZXing,Maven配置如下,jar包下载地址,自己选择版本下载,顺便推荐下Maven Repository <!-- https://mvnrepository.com/art ...
- UCOS-II学习记录
本文主要记录使用UCOS II的相关内容.包括如何完成第一个UCOS II应用程序,和如何创建任务,如何获取系统时间,和利用i3086 驱动完成时间获取,屏幕显示,按键驱动,信号量等内容. UCOS- ...
- 从聚合数据请求菜谱大全接口数据,解析显示到ListView
- CSS3动画效果之transition
CSS3中有两种方式实现动画,transition和animation+@keyframe. 两者的作用机制不一样:transition定义在可能要进行动画的元素上,对某些CSS属性进行监听,一旦CS ...
- base(function strchr)
函数原型:extern char *strchr(char *str,char character) 参数说明:str为一个字符串的指针,character为一个待查找字符. 所在库名: ...
- 【★】SPF(Dijkstra)算法完美教程