﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-天道酬勤</title><link>http://www.cppblog.com/pcyang2008/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 09 Jun 2026 21:45:38 GMT</lastBuildDate><pubDate>Tue, 09 Jun 2026 21:45:38 GMT</pubDate><ttl>60</ttl><item><title>转 在新开辟的线程里使用CActive问题 ？</title><link>http://www.cppblog.com/pcyang2008/archive/2009/05/23/85544.html</link><dc:creator>程程</dc:creator><author>程程</author><pubDate>Sat, 23 May 2009 14:19:00 GMT</pubDate><guid>http://www.cppblog.com/pcyang2008/archive/2009/05/23/85544.html</guid><wfw:comment>http://www.cppblog.com/pcyang2008/comments/85544.html</wfw:comment><comments>http://www.cppblog.com/pcyang2008/archive/2009/05/23/85544.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/pcyang2008/comments/commentRss/85544.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/pcyang2008/services/trackbacks/85544.html</trackback:ping><description><![CDATA[<div style="FONT-SIZE: 14pt; FONT-STYLE: italic; FONT-FAMILY: 宋体">首先我们有几个基本共识，或者说前提条件：<br>- (1)调度器对活动对象的调度（等待等）操作必须是同步完成的。如果调度能够<br>异步完成，调度器就需要被某种机制调度执行，而这正是调度器需要解决的问题。<br>这是一个矛盾。<br>- (2)调度器在真正开始调度的时候，必须有至少一个活动对象已经发起异步请求。<br>否则调度器将永远陷于等待状态。<br>- (3)调度器对象必须在使用之前构造完成。这个比较直观，我们不讨论这个问题。<br><br>**启动部分需要解决的问题（需求）**<br><br>这里以现有的代码进行描述。<br><br>1. 调度器启动的时候有一个活动对象在等待<br>myAO-&gt;IssueAsyncRequest();<br>CActiveSsheduler::Start();<br><br>这是最基本的要求，没有这个...难以想象啊，嘿嘿。我们构造任何解决方案首先满<br>足这个要求。<br><br>2. 调度器启动的时候有两个活动对象在等待<br>myAO1-&gt;IssueAsyncRequest();<br>myAO2-&gt;IssueAsyncRequest();<br><br>CActiveSsheduler::Start();<br><br>这个要求并不过分，事实上很多应用在启动调度器之前，都有好几个活动对象用来<br>处理不同的异步事件（主要是 observer 之类的东西在等待通知）。<br><br>3. 线程的并行问题<br>无论怎么设计，整体操作都分为两个部分：<br>1. 活动对象发起异步操作<br>2. 调度器启动<br><br>由于异步操作的处理通常都在别的线程/进程执行；在步骤 2 之前，活动对象请求<br>的的异步操作很可能已经完成。框架必须能够正确的处理这一点。<br><br>这一点可以由条件(3)保证。<br><br>4. 活动对象和调度器之间的依赖应该尽可能的少<br><br>**可能的做法**<br><br>如果不按照现有的框架，可能有两种做法：<br>- 在活动对象加入活动对象调度器，判断是否需要启动调度器<br>- 在活动对象发起第一个异步请求的时候，判断是否需要启动调度器<br><br><br>**第一个方法：加入活动对象的时候启动**<br><br>受条件（2）的限制，要求用户调用 CActiveScheduler::Add() 之前必须发起异步<br>调用:<br><br>// 构造调度器对象<br>myAO-&gt;IssueAsyncRequest(); // 发起异步请求<br>CActiveScheduler::Add(myAO); // 自动启动调度器，等待异步操作完成<br><br>显然，这不能解决"需求-2"。不能在初始化的时候启动多个活动对象。只能在第一<br>个活动对象的 RunL 里面启动其它活动对象。<br><br>另外，调度器启动之后，调用栈中包括了调用 Add 的这个函数（当前函数）。如果<br>在 Main 函数之类的地方调用 Add，自然没有问题。但是如果在活动对象的构造函<br>数（或者其它成员函数）调用 Add，就会造成活动对象和调度器的强烈耦合 ――<br>活动对象必须保证自己在调度器运行的期间一直存在。<br><br>这个方法不符合要求。<br><br>**第二个方法：发起第一个异步请求的时候启动**<br><br>CActiveScheduler::Add(myAO1);<br>CActiveScheduler::Add(myAO2);<br><br>myAO1-&gt;IssueAsyncRequest(); // 自动启动<br><br>首先这也不能解决"需求-2"。其次也存在耦合问题：怎么在发起异步请求的时候启<br>动调度器。我能想到的方法是在调用 SetActive 的时候启动，但是这个实现似乎会<br>带来无尽的恶果。<br><br>**总结**<br><br>调度器的启动不能依赖于某个活动对象的状态，应该由程序独立控制。如果启动的<br>时候不能满足条件，这是应用程序的严重BUG，需要强制程序员解决，所以 Panic<br>也是很合理的。所有这些原因都综合起来，很自然就是现在这样的一种启动方式。<br><br>应该还有很多种不同的设计，其中有些可以满足所有的需求，但是使用和实现的复<br>杂程度恐怕会大于现有的框架。可以把不爽的地方都列出来，说不定哪天能攒出来<br>一个比现有结构更好的呢 :-P</div>
<img src ="http://www.cppblog.com/pcyang2008/aggbug/85544.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/pcyang2008/" target="_blank">程程</a> 2009-05-23 22:19 <a href="http://www.cppblog.com/pcyang2008/archive/2009/05/23/85544.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>