难道CreateThread真的那么差吗?

wjb_yd 2010-08-23 02:01:03
最近一直被一个bug困扰,自己写的一个多线程的程序,有时会因为堆损坏而崩溃,始终没有找到问题所在。
因为线程函数里用了很多c运行时库的函数,所以斗胆怀疑了一下是不是用的那些函数不是线程安全的。
到网上搜了一把,都说如果线程函数用了c运行时库,一定要用_beginthreadex来创建线程。(windows核心编程看的不仔细,哎~)
难道CreateThread真的那么差吗?
目前还不知道bug是不是由于这个原因引起的...
...全文
93 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
pengzhixi 2010-08-23
  • 打赏
  • 举报
回复
好像是因为没有构造一个线程专用的一个数据结构。
macrojj 2010-08-23
  • 打赏
  • 举报
回复
人家只是没有提供运行库的全局变量块
AlanBruce 2010-08-23
  • 打赏
  • 举报
回复
是否在线程外做了线程挂起操作

如果是这样的操作很容易引起你所说的问题。。。
  • 打赏
  • 举报
回复
核心编程里面 详细讲述了原因。

_beginthreadex最终也会调用CreateThread创建线程。
1. 设计目的、意义(功能描述) 蒙特·卡罗方法(Monte Carlo method),也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法。本次大作业主要是对蒙特·卡罗方法进行并行处理,通过OpenMP、MPI、.NET、Java、Win32API等一系列并行技术和并行机制对该算法进行并行处理,从而也进一步熟悉了蒙特·卡罗方法的串行算法和并行算法,实现了用蒙特·卡罗方法计算出半径为1单位的球体的体积,体会到了并行技术在实际生活中的应用。 2. 方案分析(解决方案) 蒙特·卡罗方法(Monte Carlo method)是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。球的体积可以估算为:位于点模型内随机点个数与全体随机点个数的比值乘以包围盒的体积算的。 3. 设计分析 3.1 串行算法设计 假定球体用B表示,半径r=1单位,B1是包含B的参考立方体(在本例中是边长为2的正方体),在B1中产生N个均匀分布的伪随机点。对每个随机点检测其是否在B内,假设位于B内的随机点个数为N(in)(<=N),应用蒙特卡洛算法,则B的体积为 V=V1(N(in)/N) 其中V1是B1的体积。如果产生足够多的随机点,理论上可以获得任意逼近精度。 算法描述如下: BEGIN N=_MAX; FOR I=0;I<_MAX;I++ X=RANDOM(); Y=RANDOM(); Z=RANDOM(); IF (X*X+Y*Y+Z*Z)<=1 COUNT++; END IF; END FOR; BULK=V1*(COUNT/_MAX); END; 本算法主要是在参考立方体的选取上和定义的_MAX的值对结果影响较大,所以应该选择合适的数。 3.2 并行算法设计 对FOR循环进行划分使用两个处理器完成计算。例如对一个长为n的序列,首先划分得到两个长为n/2的序列,将其交给两个处理器分别处理;而后进一步划分得到四个长为n/4的序列,再分别交给四个处理器处理;如此递归下去最终得到结果。当然这是理想的划分情况,如果划分步骤不能达到平均分配的目的,那么结果的效率会相对较。 伪代码如下: BEGIN N=_MAX; FOR1 I=0;I<_MAX/2;I++ X1=RANDOM(); Y1=RANDOM(); Z1=RANDOM(); IF (X1*X1+Y1*Y1+Z1*Z1)<=1 COUNT1++; END IF; END FOR1; FOR2 I=_MAX/2+1;I<_MAX;I++ X2=RANDOM(); Y2=RANDOM(); Z2=RANDOM(); IF (X2*X2+Y2*Y2+Z2*Z2)<=1 COUNT2++; END IF; END FOR2; BULK=V1*((COUNT1+ COUNT2)/_MAX); END; 3.3 理论加速比分析 实验中大量数据所产生的加速比比小量数据所产生的加速比要体现得更明显,并且数据生成的并行加速比随着处理器核的增加而增加。设处理器个数为p,数据量为n,由于正常情况下该快速排序算法的复杂度为O(nlogn),并行处理的时间复杂度为O(klogk),其中k=n/p,所以并行算法的时间复杂度为O((n/p)log(n/p)),理论加速比为nlogn/((n/p)log(n/p))=p+logp. 4. 功能模块实现与最终结果分析 4.1 基于OpenMP的并行算法实现 4.1.1 主要功能模块与实现方法 利用了OpenMP里面的#omp parallel sections将对两个for循环用两个线程并行化执行,以多线程方式并行运行程序,并行的算法步骤如下: (1)初始化_max = 10000000; (2)创建两个线程; (3)由OpenMP编译指导语句控制产生并行执行代码区段; (4)将数据存放到tianqing_count; (5)各线程调用算法得出结果; 并行算法的部分代码如下: #pragma omp parallel for private(tianqing_x,tianqing_y,tianqing_z) reduction(+:tianqing_count2) for (tianqing_i = 0; tianqing_iThread newthread1 = new Thread(thread1); 创建Work类的对象work2; ThreadStart thread2 = new ThreadStart(() => work2.pSumto(c, 0, MAXN - 1)); Thread newthread2 = new Thread(thread2); stopwatch.Start(); 启动线程1和线程2; 等待进程结束; stopwatch.Stop(); 得到结果; 4.5.2 实验加速比分析 实验中创建了两个线程,通过多次测试,得出实验结果:由上面的理论加速比分析可知,当线程数为2时,理论加速比为2+log2=3.但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值3.实验加速比在2.6~2.7左右。 4.6 并行计算技术在实际系统中的应用 4.6.1 主要功能模块与实现方法 该飞机订票系统主要实现了对机票的一些基本信息进行存储和管理的功能。在系统中实现了对机票信息的增删改查,考虑到查询的方便性,对机票按照航班号进行排序,而此排序方法用并行快速排序运用进来。利用OpenMP的并行技术,对机票信息按顺序排列好,并分析了实验过程中的加速比。 4.6.2 实验加速比分析 实验中创建了两个线程,通过多次测试,得出实验结果:当数据量比较大时,加速比理论在1.9左右。数据量较大时体现出来的加速比更准确。由上面的理论加速比分析可知,当线程数为2时,理论加速比为2+log2=3.但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值3.实验加速比在2.2~2.4左右。 5. 设计体会 虽然没有按时完成作业,但这份报告花了我好几天的时间,从开始的搭建并行计算平台到最后的程序运行成功可以说是对我的一个锻炼。每一次的遇到问题与每一次的解决问题都是一个成长。每一次遇到问题和解决问题都是一种锻炼,一种尝试,从我们上并行计算课我懂得了很多电脑硬件和软件的知识,这些可能对于我们这个专业以后都是没有机会接触的,所以我觉得选择了并行计算与多核多线程技术这门课是非常正确的。对OpenMP、MPI、WIN32API、Java、.NET的并行技术有了一定的了解。在搭建MPI并行程序这块,学习的知识尤为增加,这些都是在不断的摸索、学习中学会的。 这次的大作业虽然是对以前实验的整合,但它加深了我对并行计算的印象,也使我对并行计算知识的理解更加深刻,也使我认识到了自己很多不足之处。学习并行计算的历程不会因为完成本次大作业而停止,我们是为了用知识武装大脑而学习,通过学习充实自己的生活,要努力学习,争取以后能够完成规模更大的程序。
1. 设计目的、意义(功能描述) 蒙特·卡罗方法(Monte Carlo method),也称统计模拟方法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法。本次大作业主要是对蒙特·卡罗方法进行并行处理,通过OpenMP、MPI、.NET、Java、Win32API等一系列并行技术和并行机制对该算法进行并行处理,从而也进一步熟悉了蒙特·卡罗方法的串行算法和并行算法,实现了用蒙特·卡罗方法计算出半径为1单位的球体的体积,体会到了并行技术在实际生活中的应用。 2. 方案分析(解决方案) 蒙特·卡罗方法(Monte Carlo method)是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。球的体积可以估算为:位于点模型内随机点个数与全体随机点个数的比值乘以包围盒的体积算的。 3. 设计分析 3.1 串行算法设计 假定球体用B表示,半径r=1单位,B1是包含B的参考立方体(在本例中是边长为2的正方体),在B1中产生N个均匀分布的伪随机点。对每个随机点检测其是否在B内,假设位于B内的随机点个数为N(in)(<=N),应用蒙特卡洛算法,则B的体积为 V=V1(N(in)/N) 其中V1是B1的体积。如果产生足够多的随机点,理论上可以获得任意逼近精度。 算法描述如下: BEGIN N=_MAX; FOR I=0;I<_MAX;I++ X=RANDOM(); Y=RANDOM(); Z=RANDOM(); IF (X*X+Y*Y+Z*Z)<=1 COUNT++; END IF; END FOR; BULK=V1*(COUNT/_MAX); END; 本算法主要是在参考立方体的选取上和定义的_MAX的值对结果影响较大,所以应该选择合适的数。 3.2 并行算法设计 对FOR循环进行划分使用两个处理器完成计算。例如对一个长为n的序列,首先划分得到两个长为n/2的序列,将其交给两个处理器分别处理;而后进一步划分得到四个长为n/4的序列,再分别交给四个处理器处理;如此递归下去最终得到结果。当然这是理想的划分情况,如果划分步骤不能达到平均分配的目的,那么结果的效率会相对较。 伪代码如下: BEGIN N=_MAX; FOR1 I=0;I<_MAX/2;I++ X1=RANDOM(); Y1=RANDOM(); Z1=RANDOM(); IF (X1*X1+Y1*Y1+Z1*Z1)<=1 COUNT1++; END IF; END FOR1; FOR2 I=_MAX/2+1;I<_MAX;I++ X2=RANDOM(); Y2=RANDOM(); Z2=RANDOM(); IF (X2*X2+Y2*Y2+Z2*Z2)<=1 COUNT2++; END IF; END FOR2; BULK=V1*((COUNT1+ COUNT2)/_MAX); END; 3.3 理论加速比分析 实验中大量数据所产生的加速比比小量数据所产生的加速比要体现得更明显,并且数据生成的并行加速比随着处理器核的增加而增加。设处理器个数为p,数据量为n,由于正常情况下该快速排序算法的复杂度为O(nlogn),并行处理的时间复杂度为O(klogk),其中k=n/p,所以并行算法的时间复杂度为O((n/p)log(n/p)),理论加速比为nlogn/((n/p)log(n/p))=p+logp. 4. 功能模块实现与最终结果分析 4.1 基于OpenMP的并行算法实现 4.1.1 主要功能模块与实现方法 利用了OpenMP里面的#omp parallel sections将对两个for循环用两个线程并行化执行,以多线程方式并行运行程序,并行的算法步骤如下: (1)初始化_max = 10000000; (2)创建两个线程; (3)由OpenMP编译指导语句控制产生并行执行代码区段; (4)将数据存放到tianqing_count; (5)各线程调用算法得出结果; 并行算法的部分代码如下: #pragma omp parallel for private(tianqing_x,tianqing_y,tianqing_z) reduction(+:tianqing_count2) for (tianqing_i = 0; tianqing_iThread newthread1 = new Thread(thread1); 创建Work类的对象work2; ThreadStart thread2 = new ThreadStart(() => work2.pSumto(c, 0, MAXN - 1)); Thread newthread2 = new Thread(thread2); stopwatch.Start(); 启动线程1和线程2; 等待进程结束; stopwatch.Stop(); 得到结果; 4.5.2 实验加速比分析 实验中创建了两个线程,通过多次测试,得出实验结果:由上面的理论加速比分析可知,当线程数为2时,理论加速比为2+log2=3.但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值3.实验加速比在2.6~2.7左右。 4.6 并行计算技术在实际系统中的应用 4.6.1 主要功能模块与实现方法 该飞机订票系统主要实现了对机票的一些基本信息进行存储和管理的功能。在系统中实现了对机票信息的增删改查,考虑到查询的方便性,对机票按照航班号进行排序,而此排序方法用并行快速排序运用进来。利用OpenMP的并行技术,对机票信息按顺序排列好,并分析了实验过程中的加速比。 4.6.2 实验加速比分析 实验中创建了两个线程,通过多次测试,得出实验结果:当数据量比较大时,加速比理论在1.9左右。数据量较大时体现出来的加速比更准确。由上面的理论加速比分析可知,当线程数为2时,理论加速比为2+log2=3.但由于实际操作中硬件设备以及内存分配的影响,实验加速比达不到理论值3.实验加速比在2.2~2.4左右。 5. 设计体会 虽然没有按时完成作业,但这份报告花了我好几天的时间,从开始的搭建并行计算平台到最后的程序运行成功可以说是对我的一个锻炼。每一次的遇到问题与每一次的解决问题都是一个成长。每一次遇到问题和解决问题都是一种锻炼,一种尝试,从我们上并行计算课我懂得了很多电脑硬件和软件的知识,这些可能对于我们这个专业以后都是没有机会接触的,所以我觉得选择了并行计算与多核多线程技术这门课是非常正确的。对OpenMP、MPI、WIN32API、Java、.NET的并行技术有了一定的了解。在搭建MPI并行程序这块,学习的知识尤为增加,这些都是在不断的摸索、学习中学会的。 这次的大作业虽然是对以前实验的整合,但它加深了我对并行计算的印象,也使我对并行计算知识的理解更加深刻,也使我认识到了自己很多不足之处。学习并行计算的历程不会因为完成本次大作业而停止,我们是为了用知识武装大脑而学习,通过学习充实自己的生活,要努力学习,争取以后能够完成规模更大的程序。
* 讀者來函 / 1 * 第㆓版序 / 5 第㆒版序/ 7 目錄/ 13 第0章 你㆒定要知道(導讀) / 27 這本書適合誰/ 27 你需要什麼技術基礎/ 29 你需要什麼軟硬體環境/ 29 讓我們使用同㆒種語言/ 30 本書符號習慣/ 34 磁片內容與安裝/ 34 範例程式說明/ 34 與前版本之異/ 39 如何聯絡作者/ 40 第㆒篇 勿在浮砂築高臺 - 本書技術前提/ 001 第1章 Win32 程式基本觀念/ 003 Win32 程式開發流程/ 005 需要什麼函式庫(.LIB) / 005 需要什麼表頭檔(.H) / 006 深入淺出 MFC 14 以訊息為基礎,以事件驅動之/ 007 ㆒個具體而微的 Win32 程式/ 009 程式進入點 WinMain / 015 視窗類別之註冊與視窗之誕生/ 016 訊息迴路/ 018 視窗的生命㆗樞 - 視窗函式/ 019 訊息映射(Message Map)雛形/ 020 對話盒的運作/ 022 模組定義檔(.DEF) / 024 資源描述檔(.RC) / 024 Windows 程式的生與死/ 025 閒置時間的處理:OnIdle / 027 * Console 程式 / 028 * Console 程式與DOS 程式的別/ 029 * Console 程式的編譯聯結/ 031 * JBACKUP:Win32 Console 程式設計/ 032 * MFCCON:MFC Console 程式設計/ 035 * 什麼是 C Runtime Library 的多緒版本/ 038 行程與執行緒(Process and Thread) / 039 核心物件/ 039 ㆒個行程的誕生與死亡/ 040 產生子行程/ 041 ㆒個執行緒的誕生與死亡/ 044 * 以 _beginthreadex 取代CreateThread / 046 執行緒優先權(Priority) / 048 * 多緒程式設計實例/ 050 目 錄 15 第2章 C++ 的重要性質/ 055 類別及其成員 - 談封裝(encapsulation) / 056 基礎類別與衍生類別 - 談繼承(Inheritance)/ 057 this 指標/ 061 虛擬函式與多型(Polymorphism) / 062 類別與物件大解剖/ 077 Object slicing 與虛擬函式/ 082 靜態成員(變數與函式) / 085 C++ 程式的生與死:兼談建構式與解構式/ 088 * ㆕種不同的物件生存方式/ 090 * 所謂 "Unwinding" / 092 執行時期型別資訊(RTTI) / 092 動態生成(Dynamic Creation) / 095 異常處理(Exception Handling) / 096 Template / 100 Template Functions / 101 Template Classes / 104 Templates 的編譯與聯結/ 106 第3章 MFC 六大關鍵技術之模擬/ 109 MFC 類別階層/ 111 Frame1 範例程式/ 111 MFC 程式的初始化過程/ 115 Frame2 範例程式/ 118 RTTI(執行時期型別辨識) / 122 CRuntimeClass 與類別型錄網/ 123 DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC 巨集/ 125 Frame3 範例程式/ 132 深入淺出 MFC 16 IsKindOf(型別辨識) / 140 Frame4 範例程式/ 141 Dynamic Creation(動態生成) / 143 DECLARE_DYNCREATE / IMPLEMENT_DYNCREATE 巨集/ 144 Frame6 範例程式/ 151 Persistence(永續生存)機制/ 160 Serialize(資料讀寫) / 161 DECLARE_SERIAL/IMPLEMENT_SERIAL 巨集/ 167 沒有範例程式/ 170 Message Mapping(訊息映射) / 170 Frame7 範例程式/ 181 Command Routing(命令繞行) / 191 Frame8 範例程式/ 203 * 本章回顧/ 216 第㆓篇 欲善工事先利其器- Visual C++ 5.0 開發工具 / 217 第4章 Visual C++ - 整合性軟體開發環境/ 219 安裝與組成/ 220 ㆕個重要的工具/ 234 內務府總管:Visual C++ 整合開發環境/ 236 關於project / 237 關於工具設定/ 241 Source Browser / 243 Online Help / 247 除錯工具/ 249 VC++ 除錯器/ 251 Exception Handling / 255 目 錄 17 程式碼產生器 - AppWizard / 257 東圈西點完成MFC 程式骨幹/ 258 Scribble Step0 / 270 威力強大的資源編輯器 / 294 Icon 編輯器/ 295 Cursor 編輯器/ 296 Bitmap 編輯器/ 297 ToolBar 編輯器/ 297 VERSIONINFO 資源編輯器/ 299 String Table 編輯器/ 300 Menu 編輯器/ 301 Accelerator 編輯器/ 303 Dialog 編輯器/ 304 * Console 程式的專案管理 / 305 第㆔篇 淺出 MFC 程式設計/ 309 第5章 總觀 Application Framework / 311 什麼是 Application Framework / 311 侯捷怎麼說/ 312 我怎麼說/ 314 別㆟怎麼說 / 317 為什麼使用 Application Framework / 321 Microsoft Foundation Class(MFC) / 324 白頭宮女話㆝寶:Visual C++ 與MFC / 327 縱覽MFC / 329 General Purpose classes / 330 Windows API classes / 333 深入淺出 MFC 18 Application framework classes / 334 High level abstractions / 334 Afx 全域函式/ 335 * MFC 巨集(macros) / 335 * MFC 資料型態(data type) / 338 第6章 MFC 程式設計導論 - MFC 程式的生死因果/ 343 不㆓法門:熟記 MFC 類別的階層架構/ 346 需要什麼函式庫(.LIB) / 347 需要什麼含入檔(.H) / 349 簡化的 MFC 程式架構 - 以Hello MFC 為例/ 351 Hello 程式原始碼/ 352 MFC 程式的來龍去脈/ 357 我只借用兩個類別:CWinApp 和CFrameWnd / 358 CWinApp - 取代 WinMain 的㆞位/ 359 CFrameWnd - 取代WndProc 的㆞位/ 362 引爆器 - Application object / 364 隱晦不明的WinMain / 366 AfxWinInit - AFX 內部初始化動作/ 370 CWinApp::InitApplication / 372 CMyWinApp::InitInstance / 374 CFrameWnd::Create 產生主視窗(並註冊視窗類別) / 376      * 奇怪的視窗類別名稱 Afx:b:14ae:6:3e8f / 387 視窗顯示與更新/ 389 CWinApp::Run - 程式生命的活水源頭/ 390 把訊息與處理函式串接在㆒起:Message Map 機制/394 來龍去脈總整理/ 397 Callback 函式/ 398 目 錄 19 * 閒置時間(idle time)的處理:OnIdle / 403 Dialog 與Control / 406 通用對話盒(Common Controls) / 407 本章回顧/ 409 第7章 簡單而完整:MFC 骨幹程式/ 411 不㆓法門:熟記 MFC 類別的階層架構/ 411 MFC 程式的 UI 新風貌/ 412 Document/View支撐你的應用程式/ 419 利用 Visual C++ 工具完成 Scribble step0 / 423 骨幹程式使用哪些 MFC 類別? / 423 Document Template 的意義/ 430 Scribble 的 Document/View 設計/ 436 主視窗的誕生/ 438 工具列和狀態列的誕生(Toolbar & Status bar) / 440 滑鼠拖放(Drag and Drop) / 442 訊息映射(Message Map) / 445 標準選單 File/Edit/View/Window/Help / 446 對話盒/ 449 改用CEditView / 450 第㆕篇 深入 MFC 程式設計/ 453 第8章 Document-View 深入探討/ 455 為什麼需要 Document-View(形而㆖)/ 455 Document / 457 View / 458 Document Frame(View Frame) / 459 深入淺出 MFC 20 Document Template / 459 CDocTemplate 管理 CDocument / CView / CFrameWnd / 460 Scribble Step1 的 Document(資料結構設計) / 468 MFC Collection Classes 的選用/ 469 Template-Based Classes / 471 Template-Based Classes 的使用方法/ 471 CScribbleDoc 的修改/ 473 SCRIBBLEDOC.H / 475 SCRIBBLEDOC.CPP / 477 文件:㆒連串的線條/ 481 CScribbleDoc 的成員變數/ 481 CObList / 481 CScribbleDoc 的成員函式/ 482 線條與座標點/ 484 CStroke 的成員變數/ 484 CArray / 484 CStroke 的成員函式/ 484 Scribble Step1 的View:資料重繪與編輯/ 487 CScribbleView 的修改/ 488 SCRIBBLEVIEW.H / 488 SCRIBBLEVIEW.CPP / 489 View 的重繪動作 - GetDocument 和OnDraw / 493 CScribbleView 的成員變數/ 493 CScribbleView 的成員函式/ 493 View 與使用者的交談(滑鼠訊息處理實例) / 495 ClassWizard 的輔佐/ 496 WizardBar 的輔佐/ 498 Serialize:物件的檔案讀寫/ 498 目 錄 21 Serialization 以外的檔案讀寫動作/ 499 檯面㆖的 Serialize 動作/ 501 檯面㆘的 Serialize 寫檔奧秘/ 507 檯面㆘的 Serialize 讀檔奧秘/ 514 DYNAMIC / DYNCREATE / SERIAL ㆔巨集/ 522 Serializable 的必要條件/ 527 CObject 類別/ 529 IsKindOf / 529 IsSerializable / 530 CObject::Serialize / 531 CArchive 類別/ 531 operator<< 和 operator>> / 532 效率考量/ 536 自定 SERIAL 巨集給抽象類別使用/ 537 在 CObList ㆗加入 CStroke 以外的類別/ 537 Document 與 View 交流 - 為 Scribble Step4 做準備/ 543 第9章 訊息映射與命令繞行/ 547 到底要解決什麼/ 547 訊息分類/ 549 萬流歸宗 Command Target(CCmdTarget) / 550 ㆔個奇怪的巨集,㆒張巨大的網/ 551 DECLARE_MESSAGE_MAP 巨集/ 552 訊息映射網的形成:BEGIN_/ON_/END_ 巨集/ 544 米諾托斯(Minotauros)與西修斯(Theseus) / 560 兩萬五千里長征 - 訊息的流竄/ 566 直線㆖溯(㆒般 Windows 訊息) / 567 拐彎㆖溯(WM_COMMAND 命令訊息) / 572 深入淺出 MFC 22 羅塞達碑石:AfxSig_xx 的秘密/ 580 Scribble Step2:UI 物件的變化/ 585 改變選單/ 585 改變工具列/ 588 利用 ClassWizard 連接命令項識別碼與命令處理函式/ 590 維護 UI 物件狀態(UPDATE_COMMAND_UI) / 594 本章回顧/ 599 第10 章 MFC 與對話盒/ 601 對話盒編輯器/ 602 利用 ClassWizard 連接對話盒與其專屬類別/ 606 PENDLG.H / 610 PENDLG.CPP / 610 對話盒的訊息處理函式/ 613 MFC ㆗各式各樣的MAP / 615 對話盒資料交換與查核(DDX & DDV) / 617 MFC ㆗各式各樣的DDx_ 函式/ 621 如何喚起對話盒/ 622 本章回顧/ 625 第11 章 View功能之加強與重繪效率之提昇/ 627 同時修改多個Views:UpdateAllViews 和OnUpdate / 629 在 View ㆗定義㆒個hint / 631 把 hint 傳給OnUpdate / 635 利用 hint 增加重繪效率/ 637 可捲動的視窗:CScrollView / 640 大視窗㆗的小窗口:Splitter / 650 分裂視窗的功能/ 650 目 錄 23 分裂視窗的程式概念/ 651 分裂視窗之實作/ 653 本章回顧/ 657 第12 章 印表與預覽/ 659 概觀/ 659 列印動作的背景原理/ 663 MFC 預設的印表機制/ 669 Scribble 列印機制的補強/ 685 印表機的頁和文件的頁/ 685 配置 GDI 繪圖工具/ 687 尺寸與方向:關於映像模式(座標系統) / 688 分頁/ 693 表頭(Header)與表尾(Footer)/ 695 動態計算頁碼/ 696 列印預覽(Print Preview) / 697 本章回顧/ 698 第13 章 多重文件與多重顯示/ 701 MDI 和SDI / 701 多重顯像(Multiple Views) / 703 視窗的動態分裂/ 704 視窗的靜態分裂/ 707    CreateStatic 和CreateView / 709 視窗的靜態㆔叉分裂/ 711 Graph 範例程式/ 713 靜態分裂視窗之觀念整理/ 724 同源子視窗/ 725 深入淺出 MFC 24 CMDIFrameWnd::OnWindowNew / 726 Text 範例程式/ 727 非制式作法的缺點/ 734 多重文件/ 736 新的 Document 類別/ 736 新的 Document Template / 739 新的 UI 系統/ 740 新文件的檔案讀寫動作/ 742 * 第14 章 MFC 多緒程式設計(Multi-threaded Programming in MFC) / 745 從作業系統層面看執行緒/ 745 ㆔個觀念:模組、行程、執行緒/ 746 執行緒優先權(Priority) / 748 執行緒排程(Scheduling) / 751 Thread Context / 751 從程式設計層面看執行緒/ 752 Worker Threads 和 UI Threads / 754 錯誤觀念/ 754 正確態度/ 755 MFC 多緒程式設計/ 755 探索CWinThread / 755 產生㆒個 Worker Thread / 759 產生㆒個 UI Thread / 761 執行緒的結束/ 763 執行緒與同步控制/ 763 MFC 多緒程式實例/ 766 目 錄 25 * 第15 章 定製㆒個AppWizard / 771 到底 Wizard 是什麼? / 733 Custom AppWizard 的基本操作/ 774 剖析 AppWizard Components / 779 Dialog Templates 和 Dialog Classes / 780 Macros / 781 Directives / 783 動手修改 Top Studio AppWizard / 784 利用資源編輯器修改 IDD_CUSTOM1 對話窗畫面 / 785 利用 ClassWizard 修改 CCustom1Dlg 類別/ 785 改寫 OnDismiss 虛擬函式,在其㆗定義macros / 787 修改 text template / 788 Top Studio AppWizard 執行結果/789 更多的資訊/ 790 * 第16 章 站㆖眾㆟的肩膀 - 使用 Components 和 ActiveX Controls / 791 什麼是 Component Gallery / 792 使用Components / 795 Splash screen / 795 System Info for About Dlg / 797 Tips of the Day / 798 Components 實際運用:ComTest 程式/ 799 修改 ComTest 程式內容/ 818 使用 ActiveX Controls / 822 ActiveX Control 基礎觀念:Properties、Methods、Events / 823 ActiveX Controls 的五大使用步驟/ 825 使用 "Grid" ActiveX Control:OcxTest 程式 / 827 深入淺出 MFC 26 第五篇 附錄/ 843 附錄A 無責任書評:從搖籃到墳墓 - Windows 的完全學習/ 845 * 無責任書評:MFC ㆕大㆝王/ 856 附錄B Scribble Step5 程式原始碼列表/ 873 附錄C Visual C++ 5.0 MFC 範例程式總覽/ 915 * 附錄D 以 MFC 重建 Debug Window(DBWIN) / 921 第

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧