﻿<?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>BlogJava-日出而作兮勤于外，日落而归兮忙于内-随笔分类-linux</title><link>http://www.blogjava.net/cherishchen/category/23926.html</link><description>The art of living is to know when to hold fast and when to let go</description><language>zh-cn</language><lastBuildDate>Sat, 07 Jul 2007 14:45:49 GMT</lastBuildDate><pubDate>Sat, 07 Jul 2007 14:45:49 GMT</pubDate><ttl>60</ttl><item><title>裸设备（转自网络）</title><link>http://www.blogjava.net/cherishchen/archive/2007/07/04/128034.html</link><dc:creator>cherishchen</dc:creator><author>cherishchen</author><pubDate>Wed, 04 Jul 2007 02:10:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/07/04/128034.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/128034.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/07/04/128034.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/128034.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/128034.html</trackback:ping><description><![CDATA[裸设备，也叫裸分区（原始分区），是一种没有经过格式化，不被Unix通过文件系统来读取的特殊字符设备。<br><br>1．什么叫做裸设备？<br>　　裸设备，也叫裸分区（原始分区），是一种没有经过格式化，不被Unix通过文件系统来读取的特殊字符设备。它由应用程序负责对它进行读写操作。不经过文件系<br>统的缓冲。<br><br>2．如何辨别裸设备？<br>　　在Unix的/dev 目录下，有许多文件，其中有两个大类：字符设备文件和块设备文件。字符设备特殊文件进行I/O操作不经过操作系统的缓冲区， 而块设<br>备特殊文件用来同外设进行定长的包传输。字符特殊文件与外设进行I/o操作时每次只传输一个字符。 而对于块设备特殊文件来说，它用了cache机制，在外设和<br>内存之间一次可以传送一整块数据。 裸设备使用字符特殊文件。在/dev 目录下，你可以看到许多这样的文件。<br><br>3．使用裸设备的好处<br>　　因为使用裸设备避免了再经过Unix操作系统这一层，数据直接从Disk到Oracle进行传输，所以使用裸设备对于读写频繁的数据库应用来说，可以极大地<br>提高数据库系统的性能。当然，这是以磁盘的I/O 非常大，磁盘I/O已经称为系统瓶颈的情况下才成立。 如果磁盘读写确实非常频繁，以至于磁盘读写成为系统瓶<br>颈的情况成立，那么采用裸设备确实可以大大提高性能，最大甚至可以提高至40％，非常明显。<br>　　而且，由于使用的是原始分区，没有采用文件系统的管理方式，对于Unix维护文件系统的开销也都没有了，比如不用再维护I-node，空闲块等，这也能够导<br>致性能的提高。<br><br>4．如何决定是否应该使用裸设备？<br>　　判断是否使用裸设备要从以下方面进行考虑：首先，数据库系统本身需要已经被比较好的经过了优化。优化是一门很有些技术的话题，很难简单地讲述。其次，使用<br>Unix命令来辨别是否存在磁盘读写瓶颈。比如Unix的vmstat, sar 等命令都可以较好的进行鉴别。如果决定采用裸设备，需要磁盘上还有空闲的分<br>区。否则，就要新添磁盘，或者对原有系统重新规划。<br><br>5．什么系统必须使用裸设备？<br>　　如果使用了Oracle 并行服务器选项，则必须采用裸设备来存放所有的数据文件， 控制文件，重做日志文件。只有把这些文件放到裸设备上，才能保证所有<br>Oracle实例都可以读取这个数据库的文件。这是由Unix操作系统的特性决定的。<br>　　还有一种情况是，如果你想使用异步I/O，那么在有些Unix上也必须采用裸设备。 这个需要参考具体Unix的相关文档。<br><br>6．能够使用一个磁盘的第一个分区作为裸设备吗？<br>　　可以，但是不推荐。在Unix的比较旧的版本是银行，磁盘的第一个分区常常包含这个磁盘的一些信息，以及逻辑卷的一些控制信息。若这些部分被裸设备覆盖的<br>话，磁盘就会变得不可识别，导致系统崩溃。<br>　　较新的Unix版本不会发生这样的情况，因为它们采用了更复杂的技术来管理磁盘，逻辑卷的一些信息。<br>　　但是，除非很确信不要使用磁盘的第一个分区来作为裸设备。<br><br>7．我可以把整个裸设备都作为Oracle的数据文件吗？<br>　　不行。必须让数据文件的大小稍微小于该裸设备的实际大小。至少要空出两个oracle块的大小来。<br><br>8．裸设备应该属于那个用户？<br>　　应该由root来创建裸设备，然后再分配给Oracle用户以供使用。同时还要把它归入Oracle用户所在的那个组里边（通常都是DBA）。<br><br>9．在创建数据文件时如何指定裸设备？<br>　　和普通文件没有什么太大的区别，一样都是在单引号里边写上裸设备的详细路径就可以了。举一个例子：要在创建一个表空间，使用两个裸设备，每个分别为30M的<br>大小，<br>Oracle块的大小为4K，可以用下面的命令：<br>　　CREATE TABLESPACE RAW_TS<br>　　DATAFILE '/dev/raw1' size 30712k<br>　　DATAFILE '/dev/raw2' size 30712k;<br><br>10.Oracle块的大小和裸设备有什么关系吗？<br>　　Oracle会必须是裸设备上物理块大小的倍数。<br><br>11．如何在裸设备上进行备份？<br>　　在裸设备上，不能使用Unix实用程序来进行备份，唯一的办法是使用最基本的Unix命令：DD来进行备份。比如：dd if=/dev/raw1 <br>of=/dev/rmt0 bs=16k。 dd的具体语法可以<br>参考unix手册，或者联机帮助。你也可以先用dd把裸设备上的数据文件备份到磁盘上，然后再利用Unix实用程序进一步处理。<br><br>12．如果我没有使用Oracle并行服务器选项，我可以在数据库上让一部分数据文件使用文件系统，另一部分使用裸设备吗？<br>　　可以。但是这样的话，会使备份过程更加复杂。<br><br>13．我应该把联机重做日志文件放到裸设备上吗？<br>　　这是一个极好的选择。联机重做日志文件是写操作非常频繁的文件，放到裸设备上非<br>常合适。如果你使用了并行服务器选项，那么联机重做日志文件必须放到裸设备上面。<br><br>14．可以把归档日志文件放到裸设备上吗？<br>　　不行。归档日志文件必须放到常规的Unix文件系统上面，或者直接放到磁带上面去。<br><br>15．我可以在裸设备上边放置多个数据文件吗？<br>　　不行。所以你必须在设置裸设备时非常小心。太小的话，会导致空间很快用完，太大的话，空间就白白浪费了。<br><br>16．应该把几个裸设备放到同一个物理磁盘上吗？<br>　　这样做不好。因为使用裸设备就是为了提高磁盘读写速度。而把多个裸设备放到同一个物理磁盘上会导致读写竞争，这样对于提高I/O速度是不利的。应该尽量分散<br>裸设备到不同的物理磁盘上，最好是分散到不同的磁盘控制器上。这是最佳选择。<br><br>17．需要把所有裸设备都定义成同样的大小吗？<br>　　这不是必须得，但是划分成同样的大小对于管理数据库比较有利。<br><br>18．为了在Unix上使用裸设备，我需要改变Unix核心参数吗？<br>　　不需要。但可以选择减小缓冲区的大小，如果没有别的应用也在同一台Unix机器上运行。因为运用了裸设备以后，不再使用Unix的系统缓冲区。<br><br>19．为了提高读写速度，在操作系统级别上，还有什么办法可以采取吗？<br>　　使用RAID（廉价冗余磁盘阵列）也是非常有效的办法，尤其实那种读写非常频繁的系统。<br><br>20．在考虑了以上所有方面后，还能有什么办法可以提高性能的吗？<br>　　这就需要对Oracle 进行优化，并且购买更多的磁盘和磁盘控制器，来分散I/O到不同的磁盘上。<br><br>&nbsp;&nbsp;&nbsp;&nbsp; 裸设备是一个物理概念，指的是一块物理硬盘或者是硬盘的一个分区或片区（PARTRION　OR　SLICE），在UNIX系统中，裸设备等同于字符设备，使用裸设备的好处在于可以使用第三方的软件（如数据库软件）提供的I/O处理机制，而不使用OS本身的I/O机制；逻辑卷是逻辑概念，可以包含多块物理硬盘，提供的最大的好处在于实现了存储跨盘功能，同时提供了数据复制机制，提供了数据安全保护机制<br>  <img src ="http://www.blogjava.net/cherishchen/aggbug/128034.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">cherishchen</a> 2007-07-04 10:10 <a href="http://www.blogjava.net/cherishchen/archive/2007/07/04/128034.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 让linux下的sqlplus具有回朔功能</title><link>http://www.blogjava.net/cherishchen/archive/2007/06/26/126262.html</link><dc:creator>cherishchen</dc:creator><author>cherishchen</author><pubDate>Tue, 26 Jun 2007 01:58:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/06/26/126262.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/126262.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/06/26/126262.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/126262.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/126262.html</trackback:ping><description><![CDATA[来源/作者：Blog.ChinaUnix.net 未知 2006-09-13<br>&nbsp;&nbsp;&nbsp; 参考<br>http://www.dbanotes.net/Oracle/uniread-howto.htm<br>或者 http://bbs.chinaunix.net/forum/viewtopic.php?show_type=&amp;p=3785067#3785067<br>安装uniread<br>然后将工作目录转移到$ORACLE_HOME/bin下，将sqlplus 改名为sqlpluso<br>建立脚本sqlplus,内容如下：<br>============start from here====================<br>#!/bin/bash<br>uniread sqlpluso $@<br>=============end to here=====================<br>然后使用 chmod a+x sqlplus<br>使所有用户可以执行sqlplus。现在启动sqlplus,就可以具有像bash下一样的回朔功能了。<br>   <img src ="http://www.blogjava.net/cherishchen/aggbug/126262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">cherishchen</a> 2007-06-26 09:58 <a href="http://www.blogjava.net/cherishchen/archive/2007/06/26/126262.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>各类开源协议介绍-LUPA论坛</title><link>http://www.blogjava.net/cherishchen/archive/2007/06/25/126146.html</link><dc:creator>cherishchen</dc:creator><author>cherishchen</author><pubDate>Mon, 25 Jun 2007 08:39:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/06/25/126146.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/126146.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/06/25/126146.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/126146.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/126146.html</trackback:ping><description><![CDATA[<div style="text-align: center;"><span class="tpc_title">各类开源协议介绍<br></span>LUPA论坛<br></div>
<br><span class="tpc_content"> 　　MPL
License，允许免费重发布、免费修改，但要求修改后的代码版权归软件的发起者。这种授权维护了商业软件的利益，，它要求基于这种软件得修改无偿贡献
版权给该软件。这样，围绕该软件得所有代码得版权都集中在发起开发人得手中。但MPL是允许修改，无偿使用得。MPL软件对链接没有要求。 <br><br>　　BSD开源协议 <br><br>　　BSD开源协议是一个给于使用者很大自由的协议。可以自由的使用，修改源代码，也可以将修改后的代码作为开源或者专有软件再发布。 当你发布使用了BSD协议的代码，或则以BSD协议代码为基础做二次开发自己的产品时，需要满足三个条件： <br><br>　　1． 如果再发布的产品中包含源代码，则在源代码中必须带有原来代码中的BSD协议。 <br><br>　　2． 如果再发布的只是二进制类库/软件，则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。 <br><br>　　3． 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。 <br><br>
BSD代码鼓励代码共享，但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码，也允许使用或在BSD代码上开发商业软件发布和销售，
因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议，因为可以完全控制这些第三方的代码，在必要的时候可以修改或者二
次开发。 <br><br>　　Apache Licence 2.0 <br><br>　　Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似，同样鼓励代码共享和尊重原作者的著作权，同样允许代码修改，再发布(作为开源或商业软件)。需要满足的条件： <br><br>　　1． 需要给代码的用户一份Apache Licence <br><br>　　2． 如果你修改了代码，需要再被修改的文件中说明。 <br><br>　　3． 在延伸的代码中（修改和有源代码衍生的代码中）需要带有原来代码中的协议，商标，专利声明和其他原来作者规定需要包含的说明。 <br><br>　　4． 如果再发布的产品中包含一个Notice文件，则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可，但不可以表现为对Apache Licence构成更改。 <br><br>　　Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。<br><br>　　GPL <br><br>
GPL许可证是自由软件的应用最广泛的软件许可证，人们可以修改程式的一个或几个副本或程式的任何部分，以此形成基於这些程式的衍生作品。必须在修改过
的档案中附有明显的说明：您修改了此一档案及任何修改的日期。
您必须让您发布或出版的作品，包括本程式的全部或一部分，或内含本程式的全部或部分所衍生的作品，允许第三方在此许可证条款下使用，并且不得因为此项授权
行为而收费。 <br><br>　　LGPL <br><br>　　Linux就是采用了GPL。GPL协议和BSD, Apache
Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用，但不允许修改后和衍生的代
码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux，包括商业公司的linux和linux上各种各样的由个人，组织，以及商
业软件公司开发的免费软件了。 <br><br>　　GPL协议的主要内容是只要在一个软件中使用(&#8220;使用&#8221;指类库引用，修改后的代码或者衍生代码)
GPL协议的产品，则该软件产品必须也采用GPL协议，既必须也是开源和免费。这就是所谓的&#8221;传染性&#8221;。GPL协议的产品作为一个单独的产品使用没有任何
问题，还可以享受免费的优势。 <br><br>　　由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议，对于使用GPL协议的开源代码，商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。 <br><br>　　其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似 <br><br>　　Public Domain <br><br>　　公共域授权。将软件授权为公共域，这些软件包没有授权协议，任何人都可以随意使用它。 <br><br>　　Artistic许可 <br><br>　　使作者保持对进一步开发的控制。</span>  <img src ="http://www.blogjava.net/cherishchen/aggbug/126146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">cherishchen</a> 2007-06-25 16:39 <a href="http://www.blogjava.net/cherishchen/archive/2007/06/25/126146.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> IPC和管道简介（转）</title><link>http://www.blogjava.net/cherishchen/archive/2007/06/25/126139.html</link><dc:creator>cherishchen</dc:creator><author>cherishchen</author><pubDate>Mon, 25 Jun 2007 08:31:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/06/25/126139.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/126139.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/06/25/126139.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/126139.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/126139.html</trackback:ping><description><![CDATA[<strong><span> IPC</span></strong><strong><span>和管道简介</span></strong><span> </span>
<div align="center">&nbsp;</div>
<span>本文出自<span>:http://www.china-pub.com </span>作者<span>: </span><st1:rtx w:st="on">黄浩</st1:rtx>文<span> (2001-08-08 09:00:00)</span></span><span> </span>
<div><br>1&nbsp;Interprocess&nbsp;Communication&nbsp;(IPC)<span style="font-size: 12pt; font-family: 宋体;">和管道<span lang="EN-US">Pipes&nbsp; <br><br></span>　　在<span lang="EN-US">UNIX</span>的内核环境中，要解决的一个首要问题是：如何控制和处理不同进程之间的通信和数据交换。<span lang="EN-US"> <br></span>本章中我们将通过研究一个简单的实例，看看在同一台机器的<span lang="EN-US">UNIX</span>环境下多个进程是如何运行和被我们控制的<span lang="EN-US"> <br></span>（使用<span lang="EN-US">fork()</span>方法）。<span lang="EN-US">&nbsp; <br></span>　　能够实现进程间通信的方法有：<span lang="EN-US"> <br></span>　　<span lang="EN-US">&#183;&nbsp;Pipes&nbsp; <br></span>　　<span lang="EN-US">&#183;&nbsp;Signals&nbsp; <br></span>　　<span lang="EN-US">&#183;&nbsp;Message&nbsp;Queues&nbsp; <br></span>　　<span lang="EN-US">&#183;&nbsp;Semaphores&nbsp; <br></span>　　<span lang="EN-US">&#183;&nbsp;Shared&nbsp;Memory&nbsp; <br></span>　　<span lang="EN-US">&#183;&nbsp;Sockets&nbsp; <br></span>　　本文先学习如何使用<span lang="EN-US">Pipes&nbsp;</span>方法来实现两个进程间的通信，而其它进程间通信的方法我们将在接下来的文章<span lang="EN-US"> <br></span>中详细讨论。<span lang="EN-US"> <br></span>　　在<span lang="EN-US">UNIX</span>环境下可以使用两种方式打开一个管道：<span lang="EN-US">Formatted&nbsp;Piping</span>方式和<span lang="EN-US">Low&nbsp;Level&nbsp;Piping</span>方式。<span lang="EN-US">&nbsp; <br><br>1.1&nbsp;popen()&nbsp;--&nbsp;Formatted&nbsp;Piping&nbsp; <br><br></span>　　<span lang="EN-US">FILE&nbsp;*popen(char&nbsp;*command,&nbsp;char&nbsp;*type) <br></span>　　描述了打开一个<span lang="EN-US">I/O</span>管道的方法。<span lang="EN-US"> <br></span>　　其中<span lang="EN-US">command</span>参数描述创建管道的进程，<span lang="EN-US">type</span>参数描述了管道打开的类型：<span lang="EN-US">"r"</span>表示以读方式打开，<span lang="EN-US">"w"</span>表示以<span lang="EN-US"> <br></span>写方式打开。<span lang="EN-US"> <br></span>　　<span lang="EN-US">popen()</span>的返回值是一个指针流或<span lang="EN-US">NULL</span>指针（出现错误时）。<span lang="EN-US"> <br></span>　　使用<span lang="EN-US">popen()</span>方法打开的管道，在使用完毕后必须用<span lang="EN-US">pclose(FILE&nbsp;*stream)</span>方法关闭。<span lang="EN-US"> <br><br></span>　　用户界面可以通过<span lang="EN-US">fprintf()</span>和<span lang="EN-US">fscanf()</span>方法来实现和管道的通信。<span lang="EN-US"> <br><br>1.2&nbsp;pipe()&nbsp;--&nbsp;Low&nbsp;level&nbsp;Piping&nbsp; <br><br></span>　　<span lang="EN-US">int&nbsp;pipe(int&nbsp;fd[2])&nbsp; <br></span>　　将创建一个管道和两个文件描述符：<span lang="EN-US">fd[0],&nbsp;fd[1]</span>。<span lang="EN-US"> <br></span>　　其中<span lang="EN-US">fd[0]&nbsp;</span>文件描述符将用于读操作，而<span lang="EN-US">fd[1]&nbsp;</span>文件描述符将用于写操作。<span lang="EN-US">&nbsp; <br></span>　　<span lang="EN-US">pipe()</span>的成功返回值是<span lang="EN-US">0</span>，如果创建失败将返回<span lang="EN-US">-1</span>并将失败原因记录在<span lang="EN-US">errno</span>中。<span lang="EN-US">&nbsp; <br></span>　　使用<span lang="EN-US">int&nbsp;pipe(int&nbsp;fd[2])</span>创建管道的标准编程模式如下：<span lang="EN-US"> <br></span>　　<span lang="EN-US">1</span>）<span lang="EN-US">&nbsp;</span>创建管道；<span lang="EN-US"> <br></span>　　<span lang="EN-US">2</span>）<span lang="EN-US">&nbsp;</span>使用<span lang="EN-US">fork(&nbsp;)</span>方法创建两个（或多个）相关联的进程；<span lang="EN-US"> <br></span>　　<span lang="EN-US">3</span>）<span lang="EN-US">&nbsp;</span>使用<span lang="EN-US">read()</span>和<span lang="EN-US">write()</span>方法操作管道；<span lang="EN-US"> <br></span>　　<span lang="EN-US">4</span>）<span lang="EN-US">&nbsp;</span>管道使用完毕后用<span lang="EN-US">close(int&nbsp;fd)</span>方法关闭管道。<span lang="EN-US"> <br><br></span>　　下一段程序中使用了该种<span lang="EN-US">Low&nbsp;Level&nbsp;Piping</span>的方法，实现了父进程对子进程的写操作：<span lang="EN-US"> <br><br></span>　　<span lang="EN-US">int&nbsp;pdes[2]; <br></span>　　<span lang="EN-US">pipe(pdes); <br></span>　　<span lang="EN-US">if&nbsp;(&nbsp;fork()&nbsp;==&nbsp;0&nbsp;) <br></span>　　<span lang="EN-US">{/*&nbsp;child&nbsp;*/ <br></span>　　<span lang="EN-US">close(pdes[1]);&nbsp;/*&nbsp;not&nbsp;required&nbsp;*/ <br></span>　　<span lang="EN-US">read(&nbsp;pdes[0]);&nbsp;/*&nbsp;read&nbsp;from&nbsp;parent&nbsp;*/ <br></span>　　<span lang="EN-US">..... <br></span>　　<span lang="EN-US">} <br></span>　　<span lang="EN-US">else <br></span>　　<span lang="EN-US">{&nbsp;close(pdes[0]);&nbsp;/*&nbsp;not&nbsp;required&nbsp;*/ <br></span>　　<span lang="EN-US">write(&nbsp;pdes[1]);&nbsp;/*&nbsp;write&nbsp;to&nbsp;child&nbsp;*/ <br></span>　　<span lang="EN-US">..... <br></span>　　<span lang="EN-US">} <br><br>1.4&nbsp;</span>应用实例分析<span lang="EN-US"> <br><br></span>　　本节提供了一个完整的管道应用实例，其结构说明如下：<span lang="EN-US">&nbsp; <br></span>　　<span lang="EN-US">1</span>）<span lang="EN-US">&nbsp;</span>实例含有两个程序模块<span lang="EN-US">plot.c&nbsp;(</span>主程序<span lang="EN-US">)</span>和<span lang="EN-US">plotter.c</span>；<span lang="EN-US">&nbsp; <br></span>　　<span lang="EN-US">2</span>）<span lang="EN-US">&nbsp;</span>程序运行在<span lang="EN-US">Solaris2.6</span>环境下并必须预先安装了<span lang="EN-US">GNU</span>的免费画图软件<span lang="EN-US">gnuplot&nbsp;</span>在以下目录：<span lang="EN-US">/usr/local/bin/</span>；<span lang="EN-US"> <br></span>　　<span lang="EN-US">3</span>）<span lang="EN-US">&nbsp;</span>程序<span lang="EN-US">plot.c</span>调用<span lang="EN-US">gnuplot</span>；<span lang="EN-US">&nbsp; <br></span>　　<span lang="EN-US">4</span>）<span lang="EN-US">&nbsp;Plot</span>将产生两个数据流：<span lang="EN-US">&nbsp; <br></span>　　<span lang="EN-US">y&nbsp;=&nbsp;sin(x)&nbsp; <br></span>　　<span lang="EN-US">y&nbsp;=&nbsp;sin(1/x)&nbsp; <br></span>　　<span lang="EN-US">5</span>）<span lang="EN-US">&nbsp;</span>程序将创建两个管道：每个数据流对应一个管道。<span lang="EN-US"> <br></span>　　本实例在<span lang="EN-US">Solaris2.6</span>的<span lang="EN-US">UNIX</span>环境下调试通过。<span lang="EN-US"> <br><br>plot.c</span>程序的源代码如下：<span lang="EN-US"> <br>/*&nbsp;plot.c&nbsp;-&nbsp;example&nbsp;of&nbsp;unix&nbsp;pipe.&nbsp;Calls&nbsp;gnuplot&nbsp;graph&nbsp;drawing&nbsp;package&nbsp;to&nbsp;draw <br>graphs&nbsp;from&nbsp;within&nbsp;a&nbsp;C&nbsp;program.&nbsp;Info&nbsp;is&nbsp;piped&nbsp;to&nbsp;gnuplot&nbsp;*/ <br>/*&nbsp;Creates&nbsp;2&nbsp;pipes&nbsp;one&nbsp;will&nbsp;draw&nbsp;graphs&nbsp;of&nbsp;y=0.5&nbsp;and&nbsp;y&nbsp;=&nbsp;random&nbsp;0-1.0&nbsp;*/ <br>/*&nbsp;the&nbsp;other&nbsp;graphs&nbsp;of&nbsp;y&nbsp;=&nbsp;sin&nbsp;(1/x)&nbsp;and&nbsp;y&nbsp;=&nbsp;sin&nbsp;x&nbsp;*/ <br><br>/*&nbsp;Also&nbsp;user&nbsp;a&nbsp;plotter.c&nbsp;module&nbsp;*/ <br>/*&nbsp;compile:&nbsp;cc&nbsp;-o&nbsp;plot&nbsp;plot.c&nbsp;plotter.c&nbsp;*/ <br><br>#include&nbsp;"externals.h" <br>#include&nbsp; <br>#define&nbsp;DEG_TO_RAD(x)&nbsp;(x*180/M_PI) <br><br>double&nbsp;drand48(); <br>void&nbsp;quit(); <br>FILE&nbsp;*fp1,&nbsp;*fp2,&nbsp;*fp3,&nbsp;*fp4,&nbsp;*fopen(); <br><br>main() <br>{&nbsp;float&nbsp;i; <br>float&nbsp;y1,y2,y3,y4; <br><br>/*&nbsp;open&nbsp;files&nbsp;which&nbsp;will&nbsp;store&nbsp;plot&nbsp;data&nbsp;*/ <br>if&nbsp;(&nbsp;((fp1&nbsp;=&nbsp;fopen("plot11.dat","w"))&nbsp;==&nbsp;NULL)&nbsp;|| <br>((fp2&nbsp;=&nbsp;fopen("plot12.dat","w"))&nbsp;==&nbsp;NULL)&nbsp;|| <br>((fp3&nbsp;=&nbsp;fopen("plot21.dat","w"))&nbsp;==&nbsp;NULL)&nbsp;|| <br>((fp4&nbsp;=&nbsp;fopen("plot22.dat","w"))&nbsp;==&nbsp;NULL)&nbsp;) <br>{&nbsp;printf("Error&nbsp;can't&nbsp;open&nbsp;one&nbsp;or&nbsp;more&nbsp;data&nbsp;files\n"); <br>exit(1); <br>} <br><br>signal(SIGINT,quit);&nbsp;/*&nbsp;trap&nbsp;ctrl-c&nbsp;call&nbsp;quit&nbsp;fn&nbsp;*/ <br>StartPlot(); <br>y1&nbsp;=&nbsp;0.5; <br>srand48(1);&nbsp;/*&nbsp;set&nbsp;seed&nbsp;*/ <br>for&nbsp;(i=0;;i+=0.01)&nbsp;/*&nbsp;increment&nbsp;i&nbsp;forever&nbsp;use&nbsp;ctrl-c&nbsp;to&nbsp;quit&nbsp;prog&nbsp;*/ <br>{&nbsp;y2&nbsp;=&nbsp;(float)&nbsp;drand48(); <br>if&nbsp;(i&nbsp;==&nbsp;0.0) <br>y3&nbsp;=&nbsp;0.0; <br>else <br>y3&nbsp;=&nbsp;sin(DEG_TO_RAD(1.0/i)); <br>y4&nbsp;=&nbsp;sin(DEG_TO_RAD(i)); <br><br>/*&nbsp;load&nbsp;files&nbsp;*/ <br>fprintf(fp1,"%f&nbsp;%f\n",i,y1); <br>fprintf(fp2,"%f&nbsp;%f\n",i,y2); <br>fprintf(fp3,"%f&nbsp;%f\n",i,y3); <br>fprintf(fp4,"%f&nbsp;%f\n",i,y4); <br>/*&nbsp;make&nbsp;sure&nbsp;buffers&nbsp;flushed&nbsp;so&nbsp;that&nbsp;gnuplot&nbsp;*/ <br>/*&nbsp;reads&nbsp;up&nbsp;to&nbsp;data&nbsp;file&nbsp;*/&nbsp; <br>fflush(fp1); <br>fflush(fp2); <br>fflush(fp3); <br>fflush(fp4); <br><br>/*&nbsp;plot&nbsp;graph&nbsp;*/ <br>PlotOne(); <br>usleep(250);&nbsp;/*&nbsp;sleep&nbsp;for&nbsp;short&nbsp;time&nbsp;*/ <br>} <br>} <br><br>void&nbsp;quit() <br>{&nbsp;printf("\nctrl-c&nbsp;caught:\n&nbsp;Shutting&nbsp;down&nbsp;pipes\n"); <br>StopPlot(); <br><br>printf("closing&nbsp;data&nbsp;files\n"); <br>fclose(fp1); <br>fclose(fp2); <br>fclose(fp3); <br>fclose(fp4); <br>printf("deleting&nbsp;data&nbsp;files\n"); <br>RemoveDat(); <br>} <br>The&nbsp;plotter.c&nbsp;module&nbsp;is&nbsp;as&nbsp;follows:&nbsp; <br>/*&nbsp;plotter.c&nbsp;module&nbsp;*/ <br>/*&nbsp;contains&nbsp;routines&nbsp;to&nbsp;plot&nbsp;a&nbsp;data&nbsp;file&nbsp;produced&nbsp;by&nbsp;another&nbsp;program&nbsp;*/ <br>/*&nbsp;2d&nbsp;data&nbsp;plotted&nbsp;in&nbsp;this&nbsp;version&nbsp;*/ <br>/**********************************************************************/ <br>#include&nbsp;"externals.h" <br><br>static&nbsp;FILE&nbsp;*plot1, <br>*plot2, <br>*ashell; <br><br>static&nbsp;char&nbsp;*startplot1&nbsp;=&nbsp;"plot&nbsp;[]&nbsp;[0:1.1]'plot11.dat'&nbsp;with&nbsp;lines,&nbsp; <br>'plot12.dat'&nbsp;with&nbsp;lines\n"; <br>static&nbsp;char&nbsp;*startplot2&nbsp;=&nbsp;"plot&nbsp;'plot21.dat'&nbsp;with&nbsp;lines,&nbsp; <br>'plot22.dat'&nbsp;with&nbsp;lines\n"; <br>static&nbsp;char&nbsp;*replot&nbsp;=&nbsp;"replot\n"; <br>static&nbsp;char&nbsp;*command1=&nbsp;"/usr/local/bin/gnuplot&gt;&nbsp;dump1"; <br>static&nbsp;char&nbsp;*command2=&nbsp;"/usr/local/bin/gnuplot&gt;&nbsp;dump2"; <br>static&nbsp;char&nbsp;*deletefiles&nbsp;=&nbsp;"rm&nbsp;plot11.dat&nbsp;plot12.dat&nbsp;plot21.dat&nbsp;plot22.dat"; <br>static&nbsp;char&nbsp;*set_term&nbsp;=&nbsp;"set&nbsp;terminal&nbsp;x11\n"; <br><br>void <br>StartPlot(void) <br>{&nbsp;plot1&nbsp;=&nbsp;popen(command1,&nbsp;"w"); <br>fprintf(plot1,&nbsp;"%s",&nbsp;set_term); <br>fflush(plot1); <br>if&nbsp;(plot1&nbsp;==&nbsp;NULL) <br>exit(2); <br>plot2&nbsp;=&nbsp;popen(command2,&nbsp;"w"); <br>fprintf(plot2,&nbsp;"%s",&nbsp;set_term); <br>fflush(plot2); <br>if&nbsp;(plot2&nbsp;==&nbsp;NULL) <br>exit(2); <br>} <br>void&nbsp; <br>RemoveDat(void) <br>{&nbsp;ashell&nbsp;=&nbsp;popen(deletefiles,&nbsp;"w"); <br>exit(0); <br>} <br>void <br>StopPlot(void) <br>{&nbsp;pclose(plot1); <br>pclose(plot2); <br>} <br>void <br>PlotOne(void) <br>{&nbsp;fprintf(plot1,&nbsp;"%s",&nbsp;startplot1); <br>fflush(plot1); <br>fprintf(plot2,&nbsp;"%s",&nbsp;startplot2); <br>fflush(plot2); <br>} <br>void <br>RePlot(void) <br>{&nbsp;fprintf(plot1,&nbsp;"%s",&nbsp;replot); <br>fflush(plot1); <br>} <br>The&nbsp;header&nbsp;file&nbsp;externals.h&nbsp;contains&nbsp;the&nbsp;following:&nbsp; <br>/*&nbsp;externals.h&nbsp;*/ <br>#ifndef&nbsp;EXTERNALS <br>#define&nbsp;EXTERNALS <br><br>#include&nbsp; <br>#include&nbsp; <br>#include&nbsp; <br><br>/*&nbsp;prototypes&nbsp;*/ <br><br>void&nbsp;StartPlot(void); <br>void&nbsp;RemoveDat(void); <br>void&nbsp;StopPlot(void); <br>void&nbsp;PlotOne(void); <br>void&nbsp;RePlot(void); <br>#endif&nbsp; <br><br><br></span>作者的电子邮件地址是：<span lang="EN-US">vong@21cn.com </span></span></div><img src ="http://www.blogjava.net/cherishchen/aggbug/126139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">cherishchen</a> 2007-06-25 16:31 <a href="http://www.blogjava.net/cherishchen/archive/2007/06/25/126139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>