翻译《The Old New Thing》- What does the CS_CLASSDC class style do?

What does the CS_CLASSDC class style do? - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20060602-00/?p=30993

Raymond Chen 2006年06月02日


CS_CLASSDC 类样式有什么作用?

简要

        本文讨论了CS_CLASSDC类样式的问题,指出它会导致跨窗口和线程间共享同一个设备上下文(DC),从而引发竞态条件和难以调试的错误。作者建议现代软件不应使用此样式,它仅适用于16位Windows的单线程环境。

正文

       上一次,我讨论了CS_OWNDC类样式的历史背景,以及为什么它一开始听起来是个好主意,但当你再想想时,却变成了一个可怕的想法。 CS_CLASSDC类样式也是一样的,但更糟糕,因为它继承了CS_OWNDC的所有问题,并将它们放大了。回想一下,CS_OWNDC类样式指示窗口管理器为窗口创建一个DC(设备上下文),并使用这个单一的DC响应BeginPaintGetDC的调用。

  CS_CLASSDC进一步发展了这一点,并为该类的所有窗口创建了一个DC。所以,上一次我展示的那个函数认为它对一个窗口有两个不同的DC的问题,现在甚至可能发生在不同窗口之间。 你以为你有一个窗口有一个DC,另一个窗口有另一个DC,但实际上它们是同一个! 更糟糕的是,两个线程可以同时使用同一个DC。GDI(图形设备接口)中没有任何东西禁止这样做;

        这只是一场看哪个线程的更改占上风的比赛:“最后写入者获胜”。 想象一下,两个线程恰好各自有一个来自同一个窗口类的CS_CLASSDC窗口,假设两个窗口都需要重绘。每个窗口都会收到一个WM_PAINT消息,两个线程都进入它们的绘制代码。但是这些线程不知道的是,它们正在操作同一个DC

线程A线程B
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdc = BeginPaint(hwnd, &ps);
SetTextColor(hdc, red);
SetTextColor(hdc, blue);
DrawText(hdc, …);
DrawText(hdc, …);

        线程A期望文本是红色的,它将文本颜色设置为红色,然后绘制文本。它怎么会想到就在那一刻,线程B去把它改成了蓝色?

        这是你很可能永远无法在受控条件下研究的竞态条件错误类型。你只会收到客户的bug报告,说可能每个月一次,一个项目以错误的色调出现,你可能偶尔会自己看到它,但当你设置调试器断点时,它永远不会发生。即使你添加了额外的诊断代码,你所看到的只是这个:

...
SetTextColor(hdc, red);
ASSERT(GetTextColor(hdc) == red); // 断言触发了!
DrawText(hdc, ...);

        很好,断言触发了。 你刚刚设置的颜色不在那里。 现在你打算怎么办? 也许你只会说“愚蠢的有缺陷的Windows”,然后改变你的代码为

// 愚蠢的有缺陷的Windows。出于某种原因,
// 大约每个月一次,SetTextColor不起作用
// 我们必须调用它两次。
do {
    SetTextColor(hdc, red);
} while (GetTextColor(hdc) != red);
DrawText(hdc, ...);

        甚至这也不能解决问题,因为线程B可能在GetTextColorDrawText调用之后将颜色改为蓝色。 现在,每六个月只有一次项目以错误的色调出现。

        你咒骂微软,发誓从现在开始开发Mac软件。

        好吧,所以现在我希望我说服了你,CS_CLASSDC是一个可怕的想法。 但如果它如此根本上存在缺陷,为什么它最初会存在呢?

        因为16位Windows是合作式多任务的。 在16位世界中,你不必担心另一个线程潜入并搞乱你的DC,因为,正如我已经指出的,你正在运行意味着没有其他人正在运行。这种多线程灾难场景根本不可能发生,所以CS_CLASSDC只是比CS_OWNDC稍微不那么疯狂一点。 引入具有单个进程中多个线程的抢占式多任务处理,是将我们带入了“这根本没有机会正常工作”的世界。 这个类样式的存在是为了那些在16位代码中使用它的人可以移植到Win32(只要他们承诺保持单线程应用程序),但没有任何现代软件应该使用它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/627882.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

搭建域环境

文章目录 配置域控网络安装DNS服务安装域控新建用户新建域内机器 windows server 2008是基于windows vista开发的,windows server 2008 r2是基于Win 7开发的。域控为windows server 2008. 配置域控网络 在网络共享中心配置域控IP,这里设置域控IP为&…

在centos8上生成nfs-ganesha的相关rpm

在centos8上生成nfs-ganesha的相关rpm 1.背景2.依赖环境准备2.1配置yum源2.2安装依赖包2.3拉取源代码 3编译打包3.1生成makefile3.1生成rpm 1.背景 在某些情况下,可能需要在CentOS 8上从源代码生成NFS Ganesha的RPM包,特别是当内置的软件仓库提供的NFS …

vue读取excel表格内容

vue读取excel文件内容 1. 安装第三方工具 xlsx npm install xlsx2. 在vue组件中引入xlsx import * as xlsx from xlsx3. 使用xlsx读取excel文件 html部分 <el-upload action"#" :auto-upload"false" :on-change"handleFileSelect" accept…

哪款台灯护眼效果最好,护眼效果十足的五款台灯分享

在孩子学习过程中&#xff0c;有一样物品的重要性不容忽视&#xff0c;那就是一盏提供舒适光源的台灯。面对不断增加的学业负担&#xff0c;孩子们经常需要在夜晚借助台灯的光亮进行学习&#xff0c;这已经成为了家庭生活中普遍的情景。然而&#xff0c;我们必须给予足够的关注…

云服务器修改端口通常涉及几个步骤

云服务器修改端口通常涉及几个步骤 远程连接并登录到Linux云服务器&#xff1a; 使用SSH工具&#xff08;如PuTTY、SecureCRT等&#xff09;远程连接到云服务器。 输入云服务器的IP地址、用户名和密码&#xff08;或密钥&#xff09;进行登录。 修改SSH配置文件&#xff1a…

JavaScript中带日期的操作

当我们把日期转换为Number类型的时候&#xff0c;就会变成时间戳&#xff08;毫秒&#xff09; const future new Date(2037, 10, 19, 15, 23); console.log(Number(future)); // console.log(future); //与上行代码等效● 所以我们就可以利用时间戳去做点东西&#xff0c;例…

Ceph集群扩容及数据再均衡原理分析

用户文件在Ceph RADOS中存储、定位过程大概包括&#xff1a;用户文件切割成对象、对象映射到PG、PG分组PGP、PG映射到OSD。这些过程中&#xff0c;可能涉及了大量概念和变量&#xff0c;而其实它们大部分是通过HASH、CRUSH等算法计算出来的&#xff0c;初始参数可能也就只有这么…

【源码】相亲交友系统全新UI/情感测试/婚庆中介/交友系统

【交友】相亲交友系统全新UI/情感测试/婚庆中介/交友系统 带商城&#xff0c;情感测试。 https://www.52codes.cc/codes/qt

swift语法新手快速入门,10分钟足以

编程语言教程中的第一个程序应该在屏幕上打印“Hello, world”。在 Swift 中&#xff0c;可以用一行代码实现&#xff1a; print("Hello, world!") 如果你写过 C 或者 Objective-C 代码&#xff0c;那你应该很熟悉这种形式——在 Swift 中&#xff0c;这行代码就是…

是德keysight N1911A与N1913A单通道功率计

Agilent N1911A和N1912A P系列单通道和双通道功率计以及N192XA传感器可提供宽带宽和高性能测量&#xff0c;这是确保用户的产品符合其功率规范所需要的。 P系列功率计具有30MHz视频带宽和每秒100M/s 的持续采样率&#xff0c;可进行快速、准确、可重复的功率测量。当这些功…

音视频入门基础:像素格式专题(2)——不通过第三方库将RGB24格式视频转换为BMP格式图片

音视频入门基础&#xff1a;像素格式专题系列文章&#xff1a; 音视频入门基础&#xff1a;像素格式专题&#xff08;1&#xff09;——RGB简介 音视频入门基础&#xff1a;像素格式专题&#xff08;2&#xff09;——不通过第三方库将RGB24格式视频转换为BMP格式图片 一、引…

抖音、快手、百度极速版挂机项目分享、看广告收益最多的软件!快手极速版挂机脚本,刷金币脚本、挂机项目、免费分享!

“看小说就能赚钱”、“刷视频就能赚钱”...... 号称动动手指就能赚钱的APP越来越多&#xff0c;比如各种极速版的APP、电子书APP、新闻资讯APP、搜索APP等等。 很多人也都乐此不疲&#xff0c;一天到晚就是“刷刷刷”。 最近一位“阿姨”晒各种“赚钱的APP”收入截图在业内传…

【LeetCode:23. 合并 K 个升序链表 + 链表 + 归并 + 递归】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

正点原子FreeRTOS学习笔记——列表与列表项

目录 一、什么是列表和列表项 1、概念 2、FreeRTOS代码 &#xff08;1&#xff09;列表 &#xff08;2&#xff09;列表项 &#xff08;3&#xff09;迷你列表项 二、列表与列表项初始化 1、列表初始化 2、列表项初始化 三、列表插入与删除列表项 1、原理解释 2、…

Django使用

一、根目录下安装 pip install django 二、创建djiango项目 django-admin startproject 项目名称 三、创建app python manage.py startapp app名称 四、启动 python manage.py runserver 五、编写URL与视图关系&#xff0c;相对路径 1、manage.py&#xff08;见资源绑定…

(十)Python基础练习题一(50道选择题)#Python

本文整理了Python基础知识相关的练习题&#xff0c;共50道&#xff0c;适用于刚入门初级Python想巩固基础的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-Python一&#xff09;。 1&#xff09; 2&#xff09; 3&#xff09; 4&#xff09; 5&#xff09; 6…

Vue的学习 —— <vue组件>

目录 前言 正文 一、选项式API与组合式API 二、生命周期函数 1、onBeforeMount() 2、onMounted() 3、onBeforeUpdate() 4、onUpdated() 5、onBeforeUnmount() 6、onUnmounted() 三、组件之间的样式冲突 四、父组件向子组件传递数据 1、定义props 2、静态绑定props…

java内容快速回顾+SSM+SpringBoot简要概述

文章目录 java基础知识基本知识列表面对对象堆与栈的关系值修改与引用修改异常&#xff1a;错误异常 SSMspringMVCServletSpringMVC&#xff1a;基于 Servlet的 Spring Web 框架&#xff0c; spring控制反转 IoC(Inversion of Control)面向切面 Aop MybatisJDBCMybatis SpringB…

【启明智显技术分享】工业级HMI芯片--Model系列(Model3C/Model3/Model4)烧录操作指南

前言 「Model系列」芯片是启明智显针对工业、行业以及车载产品市场推出的系列HMI芯片&#xff0c;主要应用于工业自动化、智能终端HMI、车载仪表盘、串口屏、智能中控、智能家居、充电桩显示屏、储能显示屏、工业触摸屏等领域。此系列具有高性能、低成本的特点&#xff0c;支持…

失误删除也能救回,推荐前10款手机数据恢复软件!

在手机的日常使用中&#xff0c;不可避免的会误删数据&#xff0c;这些数据可能包括照片、视频、联系人、短信等重要信息。不过好在市面上有很多优秀的手机数据恢复软件&#xff0c;可以帮助我们从各种情况下恢复丢失的数据。 本文将为您推荐十大手机数据恢复软件&#xff0c;…