第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 ...
随机推荐
- java8新特性,使用流遍历集合
在这篇“Java 8新特性教程”系列文章中,我们会深入解释,并通过代码来展示,如何通过流来遍历集合,如何从集合和数组来创建流,以及怎么聚合流的值. 在之前的文章“遍历.过滤.处理集合及使用Lambda ...
- EAGO科技人工智能+澳洲MSPL外汇平台招商
天下财经 首席运营商 EAGO外汇人工智能简介:我们将历史数据导入算法引擎,加入因子(外汇中使用的各种技术指标及各个国家的货币政策等)让计算机通过二元遗传基因.深度神经网络等算法,由机器自主深度学习. ...
- Grails笔记一:windows8.1操作系统cmd下grails命令无效
最近决定使用intellij idea工具来开发基于Grails框架的应用程序,,在安装好jdk 1.7以及配置好jdk和grails环境变量后进行grails测试,在win8.1的命令行窗口中输入以 ...
- CountDownLatch和CyclicBarrier 特点比较
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp79 并发编程中的CountDownLatch和CyclicBarri ...
- ssh keys管理工具
原文地址:https://rtyan.github.io/%E5%B7%A5%E5%85%B7/2017/09/12/ssh-keys-manager.html 引言 我有两个github账户,一个是 ...
- 闭锁——CountDownLatch
一.概念 闭锁是一个同步工具类,主要用于等待其他线程活动结束后,再执行后续的操作.例如:在王者荣耀游戏中,需要10名玩家都准备就绪后,游戏才能开始. CountDownLatch是concurrent ...
- 一,ESP8266下载和刷固件
用自己的小板测试...... 安排上呢 一, ESP8266下载和刷固件(Lua开发----体验一下lua开发的魅力所在) 二, 控制一个灯亮灭 三, TCP服务器 四, TCP客户端 五, UDP ...
- 全平台轻量级 Verilog 编译器 & 仿真环境
一直苦于 modelsim 没有Mac版本,且其体量过大,在学习verilog 时不方便使用. 终于找到一组轻量级且全平台 ( Linux+Windows+macOS ) 的编译仿真工具组. Icar ...
- 聊一聊我们都熟知的 “ Java分层 ”
一.为什么要分层. 以前的我们,写代码的时候,都在main()方法中,出现了错误,就慢慢调试,这样浪费了我们很长的时间,而我们程序员的时间是非常宝贵的 但是当我们使用分层架构的时候,就可以清晰明确的知 ...
- Flask05 cookie
1 什么是cookie 就是网站存放到你浏览器中的一部分固定内容:当你下次访问我这个网站的时候,你会把之前我存放到你浏览器中的数据带回来给我 你要先登录(用户名.密码) -> ...