﻿<?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++博客-On The Road-随笔分类-《UNIX编程艺术》读书笔记</title><link>http://www.cppblog.com/darkdestiny/category/2504.html</link><description>和C++相关的编程感悟</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 18:55:14 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 18:55:14 GMT</pubDate><ttl>60</ttl><item><title>读《UNIX编程艺术》第四章</title><link>http://www.cppblog.com/darkdestiny/archive/2006/09/10/12224.html</link><dc:creator>LOGOS</dc:creator><author>LOGOS</author><pubDate>Sun, 10 Sep 2006 10:48:00 GMT</pubDate><guid>http://www.cppblog.com/darkdestiny/archive/2006/09/10/12224.html</guid><wfw:comment>http://www.cppblog.com/darkdestiny/comments/12224.html</wfw:comment><comments>http://www.cppblog.com/darkdestiny/archive/2006/09/10/12224.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/darkdestiny/comments/commentRss/12224.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/darkdestiny/services/trackbacks/12224.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 主要是对OO语言中的厚胶合印象深刻&nbsp;&nbsp;<a href='http://www.cppblog.com/darkdestiny/archive/2006/09/10/12224.html'>阅读全文</a><img src ="http://www.cppblog.com/darkdestiny/aggbug/12224.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/darkdestiny/" target="_blank">LOGOS</a> 2006-09-10 18:48 <a href="http://www.cppblog.com/darkdestiny/archive/2006/09/10/12224.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>沉默是金</title><link>http://www.cppblog.com/darkdestiny/archive/2006/08/23/11627.html</link><dc:creator>LOGOS</dc:creator><author>LOGOS</author><pubDate>Wed, 23 Aug 2006 14:42:00 GMT</pubDate><guid>http://www.cppblog.com/darkdestiny/archive/2006/08/23/11627.html</guid><wfw:comment>http://www.cppblog.com/darkdestiny/comments/11627.html</wfw:comment><comments>http://www.cppblog.com/darkdestiny/archive/2006/08/23/11627.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/darkdestiny/comments/commentRss/11627.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/darkdestiny/services/trackbacks/11627.html</trackback:ping><description><![CDATA[作为上一笔记的补完，虽然讨论的对象是CLI程序，不过我认为作为一种有效的文化，即使GUI程序也一样受用的。<br /><br />1，过滤器类型的程序：<br />由命令行参数传递控制命令；<br />由标准输入传递输入数据，数据而已；<br />从标准输出流出的也只能是过滤后的数据，过滤的成果；发生错误的话，输出到标准错误，必须是错误，不包括程序的执行信息；<br />为了调试之类的目的，需要喋喋不休的执行信息的话，要有关闭执行信息的选项，要有控制输出等级的选项，要把这些信息输出到不会影响下游程序的地方，比如log文件。（前两个要求通常基于性能压力，喋喋不休的输出是奢侈的）<br /><br />2，不要轻易请求确认。我个人比较反感的例子就是导入注册表的时候，会弹出一个确认对话框···我不打算导入的话，会双击.reg文件吗？<br />除非有足够的理由怀疑用户可能会选NO，或者取消该行为的时候，才给出确认对话框。<br />所以MessageBox慎用。<img src ="http://www.cppblog.com/darkdestiny/aggbug/11627.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/darkdestiny/" target="_blank">LOGOS</a> 2006-08-23 22:42 <a href="http://www.cppblog.com/darkdestiny/archive/2006/08/23/11627.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>接口模式：读《UNIX编程艺术》11章感</title><link>http://www.cppblog.com/darkdestiny/archive/2006/08/21/11527.html</link><dc:creator>LOGOS</dc:creator><author>LOGOS</author><pubDate>Mon, 21 Aug 2006 07:44:00 GMT</pubDate><guid>http://www.cppblog.com/darkdestiny/archive/2006/08/21/11527.html</guid><wfw:comment>http://www.cppblog.com/darkdestiny/comments/11527.html</wfw:comment><comments>http://www.cppblog.com/darkdestiny/archive/2006/08/21/11527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/darkdestiny/comments/commentRss/11527.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/darkdestiny/services/trackbacks/11527.html</trackback:ping><description><![CDATA[首先说，接口是一个定义极多的词汇，每一本书使用接口这个词的时候都有不同的语境，代表不同的意思。<br />1，类的一个public方法/函。<br />2，一个只拥有纯虚函数的类，一般用interface定义。<br />3，程序操作界面。<br />在《UNIX编程艺术》一书中，接口是“程序同人类用户以及其他程序通讯方法的总和”。通俗的说，接口是程序获得输入数据和命令的来源。具体有这些情形，程序的执行参数，或者基于IPC的一套应用协议/数据格式，或者是人类使用的CLI或者GUI所有效的操作。与此相应的是，程序的实际功能被称为接口功能。不能很好的理解该书对接口的定义，便不能很好的阅读这一章。<br /><br />对接口的优劣评价有5项指标，不过归结只是3个词而已：简单，直观，脚本化。<br />脚本化是UNIX文化中最重要的东西了吧，在整本书中一直可以看到相关的概念，这种组件的表达方式比起链接库之类的具有更大的独立性，即使出错也不会轻易的crash主进程。<br /><br />不说废话了。下面简单列举并评述一下这一章所描述的接口模式。<br /><br />1，过滤器模式。从stdin接受数据，转换成另一种格式后输出到stdout。需要注意的是，这里是指接受数据，而非命令。该模式具有“单向流”的特点，完全是为脚本化而存在的。<br />我近段时间曾使用过几次这种模式，不过不是为了脚本化，而仅仅是为了转换格式。我所参与的project中，有些看起来很重复的代码需要重构，比较符合自动化的条件，于是书写了过滤器，协助重构工作。<br />实际的经验中要考虑的是，过滤器的过滤粒度问题，也就是吸收多大一捆数据后，才执行一次格式转换（可以称为batch）。根据实际问题的条件，batch的大小有可能是一行，也有可能是几行，也有可能是所有的数据都到达后才能执行，不过这种情形比较少见。<br />使用过滤器还有些潜规则是：<br />宽进严出，想必第一次看到这4个字的时候都以为是要限制输出内容的意思，我也是这样。不过实际上并不是指内容，而是指格式。能最大程度容忍格式不太规范的输入，而自身对输出格式要良好定义，并按这种格式输出，以便方便下一个程序解析使用。<br />过滤时，不要丢弃不需要的信息。这个信息是指从stdin读取的数据。我觉得，这个不能丢弃的信息的粒度是以batch为单位的。某个batch没有过滤处理，就直接发送到stdout；如果只是batch中的某一行数据没有过滤处理，实际上整个batch已经利用过了，而还要把那行数据保留输出，只会引起下游程序的困惑。<br />过滤时，决不增加无用数据。沉默的法则，待会说。<br /><br />2，接下来一口气说3个模式，是因为这些模式或多或少是过滤器的近亲，缺胳膊少腿的，又没有自己的特色，就能有自己的一个模式名，什么世道啊。<br />cantrip,没输入没输出，只能通过启动命令行指定运行；<br />源模式，没输入，但有输出；<br />接收器模式，有输入，但没输出；<br />看完以上，你觉得无聊吧，这3个东西也能有自己的名字···3者有脚本化能力。<br /><br />3，编译器模式···在启动命令行中指定输入数据文件和输出数据文件，没有stdin和stdout。编译器模式和过滤器模式几乎做同样的工作，但是为什么编译器模式不使用标准输入输出呢？UNIX没有把标准输入输出重定向到文件的能力吗？事实上，在windows下，把过滤器模式变成编译器的样子，大概只需要重定向一下，例如：filter.exe  &lt;  input.txt  &gt; output.txt。<br /><br />4，ed模式。第一次看到ed模式，简直毫不理解为什么过滤器模式要跑到这来换一个名字继续骗人。回到刚才聊过滤器模式提到要注意的地方，没错了，两者虽然很像，但有两个区别：<br />ed模式接受的是命令，而不是数据。每行一个命令，回车后会执行该命令所代表的功能，同时可能会变迁程序的状态。<br />ed模式需要维护会话状态。过滤器一次性的接受输入数据，一次性的处理，一次性的输出数据，在会话尺度上可以说是瞬间的。但是ed模式一次接受一条命令，执行后输出执行结果，同时程序状态可能会迁移。<br />ed模式也可以脚本化的，只是调用程序很可能要确认使用该模式程序的状态，并且脚本中的命令也要遵循这种状态才可以。<br />不过话说回来，ed模式是我们windows用户学习编程最先用到的程序了。回忆一下曾经写过的东西，都是输入回车，然后得到某种执行。呵。<br /><br />5，Roguelike模式。字符阵列GUI（如果这也可以称为GUI的话），通过单键出发（像游戏手柄一样），废弃。<br /><br />6，接口和引擎分离模式。引擎是指应用程序专用定义域的数据结构和逻辑，比喻为工作者进程也许会更贴切大家；接口负责接受用户命令，并显示结果，GUI的或者CLI的。<br />C/S模式是大家最熟悉的接口和引擎分离模式了。不过本章对此的划分可是比较细致，我看区却只是引擎部分的接口模式不同而已，接口部分还是一样的。以下模式名称都约定前者为接口，后者为引擎。<br />配置者/执行者模式。白话的说就是配置者负责配置执行者的执行行为，引擎一般使用类似于cantrip这种无需接口关心其输出的模式，并且需要接口主动调用。<br />假脱机/守护进程组合。脱机程序和守护者进程有一个约定的地方，脱机程序就是往那个地方扔东西，而守护者进程就是只打扫那个地方的东西。甚至可以说，接口和引擎完全不需要认识对方，也就不必关心对方的状态，反正把东西扔那里就没错了。<br />驱动/引擎组合；C/S组合。把两个合起来说，因为我觉得他们是一样的。同时由于大家对于C/S的熟悉程度，也无需多说。重要的问题就在设计引擎所接受的命令和返回的状态的语法上，这可以称为应用协议或者微型语言。接口需要向引擎发送命令，并获得引擎的状态，以便返回给用户。<br />综上所述，接口/引擎分离模式，接口只需要关心协议，而协议指定的工作怎么完成，就无所谓了。<br /><br />7，CLI服务器模式。不知道这样一种模式是什么意思···它要说明的只是，服务器使用标准输入输出，然后由一个守护程序，把这些输入输出连接到套接字上。这，就像是对引擎程序的拆分，服务器使用标准输入输出，可以很方便的在缺乏接口/客户端程序的情况进行本地测试与调试，等接口/客户端弄好之后，给服务器一个守护进程，守护进程启动服务器，把服务器的输入输出都连接到套接字上，系统就搭建起来了。此外，守护进程一般有做安全门卫的能力。<br />与其说这是一个模式，倒不如说是解决C/S模式调试的好方法。<br /><br />8，感谢上帝，终于到多价程序模式了，这种模式在windows下相当的普遍。也就是，程序的应用逻辑被封存在一个API库中，可以被欲使用其功能的程序编译链接。<br /><br />9，策略/机制模式。不知道这是不是接口模式，本章没有多说，但是在别的章节中老说到这个短语。<br />策略/机制模式，其核心是可配置性，可配置一切一切跟外观有关的东西，从每一根头发到每一滴血，从身体到灵魂（局外人：“那是解放者之契约”。偶：“实现汝的愿望”）。<br />无论是X，还是CEGUI，或者windows，其界面都可以配置。机制是工作的核心逻辑，而策略是一个具体的配置。<br />说CEGUI，有XXXLook这样的东西，不同的xxxLook，所看到的是不一样的东西，但是代码本身并没有变。<br />又如Windows，各种主题，Mac的，番茄花园的，都是一些指定了配置的文本行主题文件，而Windows下的显示机制，并不需要改变。<br /><br />10，写太多了，累了。<img src ="http://www.cppblog.com/darkdestiny/aggbug/11527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/darkdestiny/" target="_blank">LOGOS</a> 2006-08-21 15:44 <a href="http://www.cppblog.com/darkdestiny/archive/2006/08/21/11527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IPC,读《Unix编程艺术》某章感</title><link>http://www.cppblog.com/darkdestiny/archive/2006/08/13/11176.html</link><dc:creator>LOGOS</dc:creator><author>LOGOS</author><pubDate>Sun, 13 Aug 2006 03:06:00 GMT</pubDate><guid>http://www.cppblog.com/darkdestiny/archive/2006/08/13/11176.html</guid><wfw:comment>http://www.cppblog.com/darkdestiny/comments/11176.html</wfw:comment><comments>http://www.cppblog.com/darkdestiny/archive/2006/08/13/11176.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/darkdestiny/comments/commentRss/11176.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/darkdestiny/services/trackbacks/11176.html</trackback:ping><description><![CDATA[
		<p>UNIX文化,提倡的是一种简洁,直观,低复杂度的文化.<br />UNIX倡导多进程编程,而不是大家所熟悉的多线程编程.<br />由于进程有自己独立的地址空间,因此多进程之间的协作与交互,通关操作系统提供的各种IPC方法实现.<br />在讨论IPC的那个章节里,提出了管道,信号,临时文件,共享内存,套接字几个模型.<br /><br />我一般写东西玩的时候,总是喜欢建立控制台程序,因为输入输出库都比较简单,并且所见即得.管道/重定向之类,都是建立在标准输入/输出的基础上.这里所描述的管道/重定向,并不是在一个进程中调用CreatePipe,改变管道方向,然后用CreateProcess建立一个子进程.UNIX所用的方式类似于.bat命令,比如 dir | more,用符号"|"连接两个进程的管道.事实上,一般能用上管道/重定向的进程,都是一个过滤器,数据从标准输入进来,经过加工后从标准输出跑掉.因此,管道/重定向技术对于流水线般加工的任务,是一个相当棒的模型.<br />需要注意的是,使用管道模型的程序,通常数据流/协议(在某个任务下)是单向的.<br />总体上,在WINDOWS下像UNIX那样使用管道/重定向机制,通常是用C/C++写许多独立但是可以连接的程序,然后用bat的方式,将其按所需任务组合.如果希望在程序中可以像bat那样启动其他进程,只要用简单的system(command)函数就好了,WINAPI通常都是复杂而累赘的.<br /><br />UNIX下的信号,是对进程发出的,由进程的相应回调函数处理,程序可以重载自己的实现.这和WINDOWS下的消息比较相像,只是WM通常都需要窗口.由于信号/消息能传递的数据都比较薄弱简单,所以这通常作为一种辅助机制,和其他IPC模型共同协作.<br /><br />临时文件,是一种能解决双向沟通的模型,但是并不利于做复杂的事情,最好的用途是在简单,需要双方沟通,大数据量的情形下.使用方法大概描述为,A进程调用执行某个任务的B进程,B进程将执行结果写入A进程指定的文件,A进程使用该文件.<br />一个隐患是,一旦破坏程序知道临时文件的位置,就可能破坏该文件.<br />其实临时文件和接下来所说的共享内存在功能上并无太大区别.唯一不同的是,临时文件所使用的API,都是很容易跨平台的.<br /><br />共享内存,是一个和操作系统密切相关的IPC模型,作为生产者/消费者系统的一个性能优化的解决方案,其最大的优势便是对大型数据传递所提供的效率.但是,预防竞争/死锁是必须考虑的问题.我觉得,由于共享内存的API通常是专有的,不易于跨平台,所以使用共享内存的条件应该比较严格,必须要在性能需求高和一次数据交换量巨大的情况下才可以考虑,而且,临时文件是一个可以考虑的替代模型.<br /><br />套接字,是一个直观并且在众多操作系统中广泛使用的模型,不用说也知道是一个好东西了.<br /><br />在《UNIX编程艺术》中,认为大多数的IPC方法都是可以相互替代的,因此最重要的是选择一个尽可能使系统简单的模型.此外,特别说多线程不该是最先考虑到的方法,而是最后一个.<br />多线程将子任务糅合在一个程序中,而不是分开,增加了全局复杂度.此外,多线程带来的2个不可避免的BUG:时序问题,还有竞争/死锁的问题.纵然全局变量提升了任务之间的沟通效率,但是通常这种效率都被昂贵的锁定/解锁所抵消了.<br />特别是,使用多线程的程序所依赖的库,并非都是线程安全的,其中一旦产生的问题,会使得你麻烦重重,特别是,多线程的程序调试......由于时序问题,你自己想想都知道了.<br />因此,非要使用多线程,理想(意味着不可能存在)的约束是,线程尽量不使用全局变量;每个变量只被一个线程使用;被线程使用的变量不再被主进程使用;线程中不使用static变量.....这种约束,根本没有办法实现嘛.</p>
<img src ="http://www.cppblog.com/darkdestiny/aggbug/11176.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/darkdestiny/" target="_blank">LOGOS</a> 2006-08-13 11:06 <a href="http://www.cppblog.com/darkdestiny/archive/2006/08/13/11176.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>