用户界面对象的线程亲缘性第一篇: 窗口

news/2024/11/9 0:36:59/

不同的对象具有不同的线程亲缘性规则,但其基本原则来自古老的 16 位 Windows。

在 Windows 系统上,最重要的用户界面对象当然是窗口了。窗口对象有它自己的线程亲缘性。创建窗口的线程是与窗口具有不可分割关系的线程。非正式地说,线程”拥有”它所创建的窗口。消息仅在拥有它的线程上调度到窗口过程,一般来说,对窗口的修改应仅从拥有它的线程进行。

尽管窗口管理器允许任何线程访问窗口属性、样式和其他属性(如窗口过程),并且从窗口管理器的角度来看,此类访问是线程安全的,但加载-修改-写入序列通常应限制为窗口的所有者线程。否则,你会遇到如下图所示的竞争条件。

>> 请移步至 topomel.com 以查看图片 <<

如果从任何线程不小心修改窗口过程,则在前两行之间,第二个线程可能会更改窗口的窗口过程,从而导致 newWndProc 将错误的”上一个”窗口过程传递给 CallWindowProc。

那么,为什么 Windows 甚至允许非所有者线程首先更改窗口过程呢?

因为,众所周知,16 位 Windows 是一个协作式多任务系统,这意味着一个线程可以安全地做任何它想做的事情,因为知道没有其他线程会中断它,直到它明确放弃对CPU的控制。因此,上述代码在 16 位 Windows 中是安全的。出于兼容性原因,代码仍然是合法的,即使它不再安全。

(但是请注意,为了限制安全风险的影响范围,窗口管理器只允许拥有窗口的进程中的线程更改窗口过程。这是一个合理的限制,因为单独的地址空间意味着其他进程中的函数地址在拥有窗口的进程中毫无意义。)

总结

在 拓扑梅尔智慧办公平台 (Topomel Box) 的开发中,我始终坚守的一个编码规则是:仅在主线程中进行用户界面有关的修改,决不能在工作线程中做这种事,所有的修改要求都通过 Windows 消息来通知主线程。
对我而言,这是一个很有用的规则,一是它是简洁而不用思索的(所有的情况都直接套用这一规则,不必纠结),而是这篇文章中所提到的线程亲缘性规则。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《Thread affinity of user interface objects, part 1: Window handles》

 

 


http://www.ppmy.cn/news/53041.html

相关文章

c++11 标准模板(STL)(std::priority_queue)(三)

适配一个容器以提供优先级队列 std::priority_queue 定义于头文件 <queue> template< class T, class Container std::vector<T>, class Compare std::less<typename Container::value_type> > class priority_queue; priority_queu…

Leetcode 37 解数独

Leetcode解数独 题目描述题解1(按Board行列回溯&#xff1a;较直接) 题目描述 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次数字 1-9 在每一列只能出现一次数字 1-9 在每一个以粗实线分隔的…

Redis 主从复制

一、主从复制 1.简介 主从库之间采用读写分离的方式 读操作: 主库、从库都可以处理 写操作&#xff1a;首先写到主库执行&#xff0c;然后再将主库同步给从库。 实现读写分离&#xff0c;性能扩展 容灾快速恢复 2 主从复制步骤 创建一个目录 ,在root下创建一个myredis的目录…

销量破亿,董洁直播间凭何出圈?

近期&#xff0c;“没有五位数走不出”的董洁直播间火了…… 纵观这几年各大平台直播带货&#xff0c;火已不是什么新鲜事&#xff0c;而为何董洁的直播能火上热搜呢&#xff1f;本期&#xff0c;千瓜将解析董洁直播&#xff0c;同品牌方聊聊小红书直播的那些事儿。董洁「种草式…

RSA加解密三方调用

RSA三方调用 github项目demo 整体项目结构 ├─ExposedInterface 服务提供方的单独接口依赖包&#xff08;里面只有实体和暴露接口&#xff09; 根据服务提供者每次打包release 正式版本包 │ ├─src │ │ ├─main │ │ │ ├─java │ │ │ │ └─com │ │ │ │ └…

【Python】【进阶篇】7、Django模板系统

目录 7、Django模板系统1. Django的模板系统2. 模板系统的应用1) 模板传参2) render方法 7、Django模板系统 本节我们继续使用《Django视图函数》一节中的“Hello_my_django”函数来完成相关知识的讲解。 from django.http import HttpResponse def Hello_my_django(request)…

【mmdeploy】【TODO】使用mmdeploy将mmdetection模型转tensorrt

mmdetection转换 文章目录 mmdetection转换mmdetection 自带转换ONNX——无法测试使用mmdeploy(0.6.0)使用mmdeploy转onnx使用mmdeploy直接转tensorRT调试记录 先上结论&#xff1a;作者最后是转tensorrt的小图才成功的&#xff0c;大图一直不行。文章仅作者自我记录使用&#…

四、MyBatis获取参数值的两种方式(重点)

文章目录 四、MyBatis获取参数值的两种方式&#xff08;重点&#xff09;4.1 单个字面量类型的参数4.2 多个字面量类型的参数4.3 map集合类型的参数4.4 实体类类型的参数4.5 使用Param标识参数 四、MyBatis获取参数值的两种方式&#xff08;重点&#xff09; MyBatis获取参数值…