??xml version="1.0" encoding="utf-8" standalone="yes"?>一区二区视频在线播放,99国产一区,成人精品国产福利http://www.aygfsteel.com/killme2008/category/23659.html天行健,君子以自Z?/description>zh-cnMon, 19 Apr 2010 01:12:12 GMTMon, 19 Apr 2010 01:12:12 GMT60Google protocol buffers的Emacs扩展http://www.aygfsteel.com/killme2008/archive/2010/01/20/310206.htmldennisdennisWed, 20 Jan 2010 03:47:00 GMThttp://www.aygfsteel.com/killme2008/archive/2010/01/20/310206.htmlhttp://www.aygfsteel.com/killme2008/comments/310206.htmlhttp://www.aygfsteel.com/killme2008/archive/2010/01/20/310206.html#Feedback1http://www.aygfsteel.com/killme2008/comments/commentRss/310206.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/310206.htmlgoogle protocol buffers作ؓ(f)协议体,效率q是人满意。编辑以.protol尾的语法文Ӟ没有语法高亮很不?fn)惯Q幸好protocolbuf提供了vim和emacs的扩展。下载非win32版本的protocol buffers的压~包里,解压后有个editors目录Q里面就是两个扩展文Ӟ(x)proto.vim是提供给vim爱好者的Q?a >protobuf-mode.el是提供lemacs控的?br />     安装很简单,protobuf-mode.el加入你的Emacs加蝲路径Q然后在.emacs配置文g里加上这么两行代码:(x)
(require 'protobuf-mode)
(setq auto-mode-alist  (cons '(".proto$" . protobuf-mode) auto-mode-alist))
    require是不够的Q第二行自动把.protol尾的打开文g以protobuf-mode模式q行。运行时截图Q?br />
         
    
    工具栏上多了个ProtocolBuffers菜单Q有一些简单功能,如注释某D代码,代码跌{{等?br />


dennis 2010-01-20 11:47 发表评论
]]>
指针与数l?/title><link>http://www.aygfsteel.com/killme2008/archive/2009/02/17/254503.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 16 Feb 2009 16:05:00 GMT</pubDate><guid>http://www.aygfsteel.com/killme2008/archive/2009/02/17/254503.html</guid><wfw:comment>http://www.aygfsteel.com/killme2008/comments/254503.html</wfw:comment><comments>http://www.aygfsteel.com/killme2008/archive/2009/02/17/254503.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/killme2008/comments/commentRss/254503.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/killme2008/services/trackbacks/254503.html</trackback:ping><description><![CDATA[一、什么时候数l和指针是相同的<br /> 1、表辑ּ中的数组名(与声明不同)被编译器当作一个指向该数组W一个元素的指针<br /> 因此如a[i]q样的访问都被编译器改写或解释ؓ(f)*(a+i)的Ş式,同样取下标操作符的操作数是可交换的,所以a[3]可以写成3[a]Q不q通常你不?x)这样做?br /> <br /> 2、下标L与指针的偏移量相同,下标*sizeof(元素cd)是偏移数组起始地址的实际字节数?br /> <br /> 3?#8220;作ؓ(f)函数参数的数l名”{同于指针,M传递给函数的数l参数都?x)被转换成指针,q是Z效率考虑Q避免了数组的拷贝。在函数内部Q数l参数都被转换成一个指针,要牢记这一点,因此如:(x)<br /> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000ff;">void</span><span style="color: #000000;"> test(</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> a[</span><span style="color: #000000;">10</span><span style="color: #000000;">])<br /> {<br />    printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(a));<br /> }</span></div> <br /> 昄应该打印指针大小4Q而非数组大小。另外,注意数组参数的地址跟数l参数第一个元素的地址q不相等Q在表达式中两者一_但是在函数调用中Q由于数l参数指针也是(f)时变量,因此两者的地址是不一L(fng)?br /> 可以通过下列E序观察Q?br /> <br /> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000;">#include </span><span style="color: #000000;"><</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> #include </span><span style="color: #000000;"><</span><span style="color: #000000;">stdlib.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> test1(</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> a[])<br /> {<br />     printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">&a=%x,&(a[0])=%x,&(a[1])=%x\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">&</span><span style="color: #000000;">a,</span><span style="color: #000000;">&</span><span style="color: #000000;">(a[</span><span style="color: #000000;">0</span><span style="color: #000000;">]),</span><span style="color: #000000;">&</span><span style="color: #000000;">(a[</span><span style="color: #000000;">1</span><span style="color: #000000;">]));<br /> }<br /> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> test2(</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">b)<br /> {<br />     printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">&b=%x,&(b[0])=%x,&(b[1])=%x\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">&</span><span style="color: #000000;">b,</span><span style="color: #000000;">&</span><span style="color: #000000;">(b[</span><span style="color: #000000;">0</span><span style="color: #000000;">]),</span><span style="color: #000000;">&</span><span style="color: #000000;">(b[</span><span style="color: #000000;">1</span><span style="color: #000000;">])); <br /> }<br /> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> argc, </span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">argv[])<br /> {<br />   </span><span style="color: #0000ff;">char</span><span style="color: #000000;"> ga[]</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">hello</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />   printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">&ga=%x,&(ga[0])=%x,&(ga[1])=%x\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">&</span><span style="color: #000000;">ga,</span><span style="color: #000000;">&</span><span style="color: #000000;">(ga[</span><span style="color: #000000;">0</span><span style="color: #000000;">]),</span><span style="color: #000000;">&</span><span style="color: #000000;">(ga[</span><span style="color: #000000;">1</span><span style="color: #000000;">])); <br />   test1(ga);<br />   test2(ga);<br />   system(</span><span style="color: #000000;">"</span><span style="color: #000000;">pause</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />   </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">;<br /> }<br /> </span></div> <br /> <br /> 二、指针跟数组什么时候不?br /> 1、如果定义了一个数l,在其他文件对它进行声明也必须声明为数l,定义和声明必d配,指针也是如此?br /> 2、指针始l是指针Q它l不可以写成数组。可以用下标形式讉K指针的时候,一般都是指针作为函数参数时Qƈ且你知道传递给函数的实际是一个数l?br /> 3、数l名是不可改变的左|因此?br /> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000ff;">int</span><span style="color: #000000;"> array[</span><span style="color: #000000;">100</span><span style="color: #000000;">],array2[</span><span style="color: #000000;">100</span><span style="color: #000000;">];<br /> array</span><span style="color: #000000;">=</span><span style="color: #000000;">array2;<br /> array++;<br /> array--;<br /> </span></div>   <br /> 都将出错Q但是在函数内部Q?br /> <br /> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000ff;">int</span><span style="color: #000000;"> array2[</span><span style="color: #000000;">100</span><span style="color: #000000;">];<br /> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> fun(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> array[])<br /> {<br />   array</span><span style="color: #000000;">=</span><span style="color: #000000;">array2;<br /> }</span></div> <br /> 却可以,因ؓ(f)在函数内部array虽然被声明ؓ(f)数组实际上却是指针?br /> <br /> <br /> <br /> <br /> <br /> <br /><img src ="http://www.aygfsteel.com/killme2008/aggbug/254503.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/killme2008/" target="_blank">dennis</a> 2009-02-17 00:05 <a href="http://www.aygfsteel.com/killme2008/archive/2009/02/17/254503.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再谈Selector的wakeupҎ(gu)http://www.aygfsteel.com/killme2008/archive/2009/02/01/252835.htmldennisdennisSun, 01 Feb 2009 03:15:00 GMThttp://www.aygfsteel.com/killme2008/archive/2009/02/01/252835.htmlhttp://www.aygfsteel.com/killme2008/comments/252835.htmlhttp://www.aygfsteel.com/killme2008/archive/2009/02/01/252835.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/252835.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/252835.html?/a>Q?a >?/a>Q,感叹javaZ跨^C?#8220;很傻很天?#8221;。最q学?fn)用ACEQ才知道q个解决办法倒不是java开创的QACE也是q样搞的。java nio中Selector的wakeupҎ(gu)Q类gACE_Select_Reactor的notify机制Q可以从非select调用的线E去唤醒d在select调用上的selectU程Q当然ACE_Select_Reactor的notify强大多了Q可以实现event handler的无限扩宏VACE_Select_Reactor的notify的实现是通过ACE_PipeQ在ACE_Pipe中可以清晰地看到针对win32q_是采用了TCPq接Q?br />
#if defined (ACE_LACKS_SOCKETPAIR) || defined (__Lynx__)
  ACE_INET_Addr my_addr;
  ACE_SOCK_Acceptor acceptor;
  ACE_SOCK_Connector connector;
  ACE_SOCK_Stream reader;
  ACE_SOCK_Stream writer;
  
int result = 0;
if defined (ACE_WIN32)
  ACE_INET_Addr local_any  (static_cast
<u_short> (0), ACE_LOCALHOST);
else
  ACE_Addr local_any 
= ACE_Addr::sap_any;
# endif 
/* ACE_WIN32 */

  
// Bind listener to any port and then find out what the port was.
  if (acceptor.open (local_any) == -1
      
|| acceptor.get_local_addr (my_addr) == -1)
    result 
= -1;
  
else
    {
      ACE_INET_Addr sv_addr (my_addr.get_port_number (),
                             ACE_LOCALHOST);

      
// Establish a connection within the same process.
      if (connector.connect (writer, sv_addr) == -1)
        result 
= -1;
      
else if (acceptor.accept (reader) == -1)
        {
          writer.close ();
          result 
= -1;
        }
    }

  
// Close down the acceptor endpoint since we don't need it anymore.
  acceptor.close ();

    在类unixq_是采用STREAMS道Q在一些遗留的unixq_上是socketpair()。ؓ(f)什么在win32上采用TCPq接的方式呢Q原因不是什么性能、资源问题,也不是因为windows道消耗的资源比tcp多,而是׃winsock的select函数Qjava nio的select在win32下是使用select实现的)是无法监管道事件的Q也是说无法将windows道加入到fd_set?Z做到可移植,才在win32上采用了TCPq接的方式来实现。这一点在blog上篇的新回复中已l有人提到?br />

dennis 2009-02-01 11:15 发表评论
]]>
安装配置Emacs-railshttp://www.aygfsteel.com/killme2008/archive/2008/11/23/242067.htmldennisdennisSat, 22 Nov 2008 18:22:00 GMThttp://www.aygfsteel.com/killme2008/archive/2008/11/23/242067.htmlhttp://www.aygfsteel.com/killme2008/comments/242067.htmlhttp://www.aygfsteel.com/killme2008/archive/2008/11/23/242067.html#Feedback2http://www.aygfsteel.com/killme2008/comments/commentRss/242067.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/242067.html  1、从 http://rubyforge.org/projects/emacs-rails 下蝲最新emacs-railsQ解压文件到~/.emacs.d/rails 目录
 2、根据READMEQ你需要下载三个依赖库Q?br />
cd ~/.emacs.d/rails
wget http:
//www.kazmier.com/computer/snippet.el
wget http:
//www.webweavertech.com/ovidiu/emacs/find-recursive.txt
mv find
-recursive.txt find-recursive.el

wget http:
//svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/misc/inf-ruby.el?view=co
mv inf
-ruby.el\?view=co inf-ruby.el

3、将ruby源代码目录下?misc子目录中的emacs扩展文g拯?usr/share/emacs/site-lisp/目录下:(x)
sudo cp /home/dennis/backup/ruby-1.8.7-p72/misc/*.el /usr/share/emacs/site-lisp/

4、在~/.emacsd两行代码Q加载emacs-rails
(setq load-path (cons "~/.emacs.d/rails" load-path))
(require 
'rails)

    搞定Q看h挺强(zhn)的Q在菜单兰多了个ROR菜单Q需要熟(zhn)下快捷键?br />


dennis 2008-11-23 02:22 发表评论
]]>
ubuntu下解决Ruby安装后缺openssl的问?/title><link>http://www.aygfsteel.com/killme2008/archive/2008/11/23/242066.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 22 Nov 2008 17:34:00 GMT</pubDate><guid>http://www.aygfsteel.com/killme2008/archive/2008/11/23/242066.html</guid><wfw:comment>http://www.aygfsteel.com/killme2008/comments/242066.html</wfw:comment><comments>http://www.aygfsteel.com/killme2008/archive/2008/11/23/242066.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/killme2008/comments/commentRss/242066.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/killme2008/services/trackbacks/242066.html</trackback:ping><description><![CDATA[    一开始尝试?br />     sudo apt-get install libopenssl-ruby1.8<br />     安装是安装成功了Q但是仍然提C找不到openssl。还是决定从源码安装Q首先确保ubuntu安装了opensslQ?br />     sudo apt-get install openssl<br />     sudo apt-get install libssl-dev<br />     sudo apt-get install libssl0.9.8<br />     <br />     然后q入ruby源码目录下的/ext/openssl<br />     cd RUBY_SOURCE/ext/openssl<br />     <a title="" >ruby</a> extconf.rb<br />     make <br />     sudo make install<br /> <br /><img src ="http://www.aygfsteel.com/killme2008/aggbug/242066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/killme2008/" target="_blank">dennis</a> 2008-11-23 01:34 <a href="http://www.aygfsteel.com/killme2008/archive/2008/11/23/242066.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memcached1.2新增启动参数初探http://www.aygfsteel.com/killme2008/archive/2008/08/07/220774.htmldennisdennisThu, 07 Aug 2008 14:16:00 GMThttp://www.aygfsteel.com/killme2008/archive/2008/08/07/220774.htmlhttp://www.aygfsteel.com/killme2008/comments/220774.htmlhttp://www.aygfsteel.com/killme2008/archive/2008/08/07/220774.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/220774.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/220774.html     memcached 1.2新增加了几个参数Q试着做下ȝQ有错误h正:(x)
-U <num> 监听UDP端口Q默认是11211端口

-f <factor> q个参数很重要,用于讄chunk大小的递增因子。memcached的存储模型类g个二l数l:(x)slab->chunk->itemQ每个slab大小?MQslab中的chunk的大等于chunk的初始大乘以f^sidQf的sidơ方Q,其中sid是当前slab的idQchunk的默认大在1.1?字节Q在1.2?0字节。f是chunk的递增倍数Q在1.1固定?Q在1.2可通过-f参数讄Q默认ؓ(f)1.25。memcachd存储的item大小一般会(x)比存储的chunk size,那么有部分I间被浪费,Z量节省内存Q正设|?f参数显的非帔R要,通过计算量让chunk的大接q或者略大于存储的item的大?br />
-M q个参数?.1中就有了。这个参数用于在内存溢出的时候,止自动U除~存数据QLRUQ,替代的是q回一个error?br />
-s <size> 讄分配litem的key、value和flag的最字节数Q默认是48字节。根据你存储的item大小适当调整q个|可以更有效地利用内存?br />
-t <num> 讄处理h的线E数。这个参C在编译memcached启用U程时有效。这个参数通常讄的大等于CPU个数?br />



dennis 2008-08-07 22:16 发表评论
]]>
lua 5.0的实玎ͼ译)4,5http://www.aygfsteel.com/killme2008/archive/2008/04/07/191324.htmldennisdennisMon, 07 Apr 2008 09:55:00 GMThttp://www.aygfsteel.com/killme2008/archive/2008/04/07/191324.htmlhttp://www.aygfsteel.com/killme2008/comments/191324.htmlhttp://www.aygfsteel.com/killme2008/archive/2008/04/07/191324.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/191324.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/191324.html4?/span> ?/span>

    Table?/span>lua的主要——实际上Q也是唯一的——数据结构?/span>Table不仅在语a中,同时也在语言的实C扮演着重要角色?/span>Effort spent on a good implementation of tables is rewarded in the language,because tables are used for several internal tasks, with no qualms about performance。这有助于保持实现的y。相反的Q?/span>M其他数据l构的机制的~Z也ؓ(f)table的高效实现带来了很大压力

       Lua中的table是关联数l,也就是可以用M值做索引Q除?/span>nilQ,也可以持有Q何倹{另外,table是动态的Q也是说当加进数据的时候它们将增长Q给q今不存在的域赋|而移除数据的时候将萎羃Q给域赋nil|?/span>

不像大多数其他脚本语aQ?/span>lua没有数组cd。数l被表示Z整数做键?/span>table。用table作ؓ(f)数组对于语言是有益的。主要的Q益处)显而易见:(x)luaq不需要操U表和数l的两套不同的运符。另外,E序员不用对两种实现做出艰难选择。在lua中实现稀疏数l是轻而易丄。例如,?/span>Perl里面Q如果你试去跑$a[1000000000]=1 q样的程序,你能跑出个内存溢出!Q?/span>you can run out of memoryQ,因ؓ(f)它触发了一?/span>10亿个元素的数l的创徏Q译注,Perl的哲学是Q去除不必要的限Ӟ。而等L(fng)luaE序 a={[1000000000]=1},Q只是)创徏了有一个单独的的表(而已Q?/span>


直到lua 4.0Q?/span>table都是作ؓ(f)hash表严格地实现Q所有的pair都被昑ּC存?/span>Lua5.0引入了一个新法来优化作为数l的tableQ它?yu)以整数为键?/span>pair不再是存储键而是优化成存储值在真正的数l中。更_地说Q在lua 5.0中,table被实Cؓ(f)一个؜合数据结构:(x)它们包括一?/span>hash部分和一个数l部分。图2展示了一个有"x" 9.3, 1 100,2 200, 3 300对子的表的一U可能结构。注意到数组部分在右边,q没有存储整数的key。这个划分仅仅是在一个低的实现层ơ进行的Q访?/span>table仍然是透明的,甚至在虚拟机内部Q访?/span>tableQ也是如此?/span>TableҎ(gu)内容自动q且动态地对两个部分进行适配Q数l部分试图从1?/span>n的相应地存储|兌非整数键或者整数键过数组范围的D存储?/span>hash部分?/span>

当一?/span>table需要增长时Q?/span>lua重新计算hash部分和数l部分的大小。Q一部分都可能是I的。重新计后的数l大是臛_是当前用的数组部分?/span>1?/span>n的一半情况下的最?/span>n|原文Q?/span>The computed size of the array part is the largest n such that at least half the slots between 1 and n are in useQ(E疏数l时避免费I间Q,q至有一个(元素Q处?/span>n/2+1?/span>n的槽中(?/span>n?/span>2整除Ӟ避免n的这L(fng)数组大小Q。计完大小后,lua创徏?#8220;?#8221;的部分ƈ?#8220;?#8221;的部分的元素重新插入到的“?#8221;的部分。作Z个例子,假设a是一个空表;它的数组部分?/span>hash部分的大都?/span>0。当我们执行a[1]=vӞq个表需要增长到_容纳新的键?/span>Luaؓ(f)新的数组部分的大选择n=1Q带有一个项1vQ?/span>hash部分仍然保持为空?/span>

q个混合的方案有两个优点。首先,讉K以整Cؓ(f)键的值加快了Q因Z再需要Q何的散列行ؓ(f)。其ơ,也是最重要的,数组部分占用的内存大概是数l部分存储在hash部分时的一半,因ؓ(f)key在数l中是隐式的Q译注:(x)也就是数l的下标Q而在hash部分却是昑ּ的。因而,当一?/span>table被用作数l的Ӟ它表现的像一个数l,只要整数键是密集。另外,不用?/span>hash部分付出M内存和时间上的惩|,因ؓ(f)它(译注Q?/span>hash部分Q甚至都不存在。相反的控制Q如?/span>table被用作关联数l而非一个数l,数组部分可能是I的。这些内存上的节省是比较重要的,因ؓ(f)luaE序l常创徏一些小?/span>tableQ例?/span>table被用来实现对象(ObjectQ(译注Q也是?/span>table来模仿对象,有点cMjavascript中的jsonQ?/span>

Hash部分采用Brent's variation[3]的组合的铄发散表。这?/span>table的主要不变式是如果一个元素没有在它的主要位置上(也就?/span>hash值的原始位置Q,则冲H的元素在它自己的主要位|上。换句话_仅当两个元素有相同的主要位置Q也是在当?/span>table大小情况下的hash|时才有冲H的。没有二U冲H。正因ؓ(f)那样Q这?/span>table的加载因子可以是100%而没有性能上的损失。这部分不是很明白,附上原文Q?/span>

The hash part uses a mix of chained scatter table with Brent's variation [3].

A main invariant of these tables is that if an element is not in its main position

(i.e., the original position given by its hash value), then the colliding element

is in its own main position. In other words, there are collisions only when two

elements have the same main position (i.e., the same hash values for that table

size). There are no secondary collisions. Because of that, the load factor of these

tables can be 100% without performance penalties.

 

 

5、函数和闭包

?/span>lua~译一个函数的时候,它生一个模型(prototypeQ,包括了函数的虚拟机指令、常量|数字Q字W串字面量等Q和一些调试信息。运行的时候,无论何时lua执行一?/span>function…end表达式,它都创徏一个新的闭包。每个闭包都有一个引用指向相应的模型Q一个引用指向环境(environmentQ(一张查扑օ局变量的表Q译注:(x)指所谓环境就是这样一张表Q,和一l用来访问外?/span>local变量的指?/span>upvalue的引用?/span>

词法范围以及first-class函数的组合导致一个关于(如何Q访问外?/span>local变量的著名难题。考虑?/span>3中的例子。当add2被调用的时候,它的函数体(bodyQ部分引用了外部local变量x (函数参数?/span>lua里是local变量Q译注:(x)x是所谓的自由变量Q这里Ş成了闭包)。尽如此,?/span>add2被调用时Q生?/span>add2的函?/span>add已经q回。如果在栈中生成变量xQ(x在栈的)其栈槽将不复存在。(译注Q此处的意思应该是说如果在栈保存变?/span>xQ那么在调用add2的时候,add函数早已l返回,x也在add2调用前就不在栈里头了Q这是那个著名NQ?/span>


 

 

大多数过E语a通过限制词法范围Q例?/span>pythonQ,不提?/span>first-class函数Q例?/span>PascalQ,或者都两者都采用Q例?/span>c,译注Q也是?/span>c既不把函数当一{公民,也限制词法范_来回避这个问题。函数式语言没有那些限制。围l着非纯_函数语a比如Scheme?/span>ML的研I已l生了大量的关于闭包的~译技术的知识Q参?/span>[19, 1, 21]Q。尽如此,q些工作q没有尽力去限制~译器的复杂性。以优化?/span>Scheme~译?/span>Bigloo的控制流?/span>


析阶Dؓ(f)例,Q它的实玎ͼ?/span>lua实现?/span>10倍还大:(x)Bigloo 2.6f?/span>Cfa模块源码?/span>106,350?/span> VS. 10,155行的lua5.0核心。正如第2部分已经解释q的Q原因)Q?/span>lua需要简单?/span>

Lua使用了一个称?/span>upvalue的结构来实现闭包。Q何外?/span>local变量的访问都是通过一?/span>upvalue间接q行的?/span>Upvalue初始指向的是变量存活位置的栈槽(参见?/span>4的左半部分)。当变量Q?/span>xQ已l离开作用域(译注Q也是q里?/span>add函数q回ӞQ它?yu)pUdupvaluel构本n一个槽中(参见?/span>4的右半部分)。因为(对变量的Q访问是间接地通过upvaluel构中的一个指针进行的Q因此这个迁Ud于Q何写或者读该变量的代码都是透明的。不像它的内嵌函敎ͼ译注Q例子的add2Q它是指外部函数addQ,声明变量的函数访问该变量像讉K它的local变量一P(x)直接到栈?/span>

通过每个变量最多创Z?/span>upvaluel构q且在必要的时候复用它们,可变状态得以在闭包之间正确地共享。ؓ(f)了保证这一U束Q?/span>lual持一个链表,里面是一个栈里(?/span>4中的pending vars列表Q的所?/span>open upvalueQ所?/span>open upvalueQ是指仍然指向栈?/span>upvaluel构Q。当lua创徏一个新的闭包的时候,它遍历所有的外部local变量。对于每个(外部localQ变量,如果它在列表中找C?/span>open upvalueQ那么它?yu)复用这?/span>upvaluel构。否则,lua创Z个新?/span>upvalueq将它放入链表。注意到列表搜烦只是探测了少数几个节点,因ؓ(f)列表最多包含一个被内嵌函数使用?/span>local变量的项。当一?/span>closed upvalue不再被Q何闭包引用的时候,它最后将被当作垃圑ƈ回收?/span>

一个函数允许访问一个不是它的直接外围函数的外部local变量Q只要(q个local变量Q是外部函数的(outer functionQ。在那种情况下,甚至在闭包被创徏的时候,Q外?/span>localQ变量可能就不在栈里了?/span>Lua使用扁^闭包Q?/span>flat closuresQ解册U情?/span>[5]。通过扁^闭包Q一个函数无Z时去讉K一个不属于它的外围函数的外部变量,q个变量都将q入外围函数的闭包。从而当一个函数被实例化的时候,所有进入它闭包的变量要么在外围函数的栈里面Q要么在外围函数的闭包里?/span>



dennis 2008-04-07 17:55 发表评论
]]>
lua 5.0的实玎ͼ译)1,2,3http://www.aygfsteel.com/killme2008/archive/2008/04/07/191314.htmldennisdennisMon, 07 Apr 2008 09:25:00 GMThttp://www.aygfsteel.com/killme2008/archive/2008/04/07/191314.htmlhttp://www.aygfsteel.com/killme2008/comments/191314.htmlhttp://www.aygfsteel.com/killme2008/archive/2008/04/07/191314.html#Feedback2http://www.aygfsteel.com/killme2008/comments/commentRss/191314.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/191314.html三个多月前翻译的Q今天又扑և来看?后面的待整理下l发,有错误的地方请不吝赐教?br />

原文Qhttp://www.tecgraf.puc-rio.br/~lhf/ftp/doc/jucs05.pdf

译Qdennis zhuang (killme2008@gmail.com)  http://www.aygfsteel.com/killme2008

转蝲h明出处,谢谢?/span>

 

摘要Q我们讨Zlua 5.0实现的主要新Ҏ(gu):(x)Z寄存器的虚拟机,优化表的新算法以便(表Q用作数l,闭包的实玎ͼ以及coroutinesQ译注:(x)协程Q?/span>

关键?/span>: compilers, virtual machines, hash tables, closures, coroutines

 

1.    介绍

Lua作ؓ(f)内部使用的开发工兯生于学术实验室中Q现在却已经被世界范围内许多工业U项目所采用Q广泛应用于游戏领域?/span>LuaZ么能获得q样q泛的应用呢Q我们认为答案就来源于我们的设计和实现目标上Q提供一U简单、高效、可UL和轻量的嵌入式脚本语言。这?/span>Lua?/span>1993q诞生以来我们一直追求的目标Qƈ在(语言的)演化q程中遵守?/span>q些Ҏ(gu),以及Lua一开始就被设计成嵌入大型应用的事实,才它在早期被工业界所接受?/span>

 

q泛的应用生了对(新的Q语a的特性的需求?/span>Lua的许多特性来自于工业需求和用户反馈的推动。重要的例如lua 5.0引入?/span>coroutines和即到来的Lua 5.1改进的垃圾收集实玎ͼq些Ҏ(gu)对于游戏(~程Q特别重要?/span>

 

在这论文中Q我们讨Zlua 5.0相比?/span>lua 4.0的主要新Ҏ(gu):(x)

Z寄存器的的虚拟机Q传l上Q绝大多数虚拟机的实际执行都是基于栈Q这个趋势开始于Pascal?/span>Pmachine,延箋C天的java虚拟机和微Y?/span>.net环境。目前,管对于Z寄存器的虚拟机的兴趣逐渐增多Q比?/span>Perl6计划中的新的虚拟机(ParrotQ将是基于寄存器的)Q但是就我们所知,lua 5.0是第一个被q泛使用的基于寄存器的虚拟机。我们将在第7部分描述q个虚拟机?/span>

 

优化表的新算法以便作为数l:(x) 不像其他脚本语言Q?/span>Luaq没有提供数l类型?/span>Lua使用整数索引的普通表来实现数l作为替代?/span>Lua 5.0使用了一个新的算法,可以表是否被作为数l用,q且可以自动关联着数字索引的值存储进一个真实的数组Q而不是将它们放进Hash表。在W?/span>4部分我们讨个算法?/span>

 

闭包的实玎ͼ(x)lua 5.0在词法层ơ上支持first-class 函数Q译注:(x)函CZ{公民)。这个机制导致一个著名的语言NQ用基于数l的栈来存储Ȁz记录?/span>Lua 使用了一个新办法来实现函数闭包,保存局部变量在Q基于数l)的栈(stack)上,当它们被内嵌函数引用而从作用域逸出的时候才它们{Ud?/span>(heap)上。闭包的实现在W?/span>5部分讨论?/span>

dcoroutinesQ?/span> lua 5.0语言引入?/span>coroutines。尽?/span>coroutines的实现较Zl,但ؓ(f)了完整性我们将在第6部分做个短的概况介绍?/span>

 

其他部分是ؓ(f)了讨论的完整性或者提供背景资料。在W?/span>2部分我们介绍?/span>lua的设计目标以及这个目标如何驱动实现的概况。在W?/span>3部分我们介绍?/span>lua是如何表C值的。尽就q个q程本n没有什么新意,但是ZQ理解)其他部分我们需要这些资料。最后,在第8部分Q我们介l了一个小型的基准试来得C些结论?/span>

 

2.    lua设计和实现概?/span>

在介l部分提到过的,lua实现的主要目标是Q?/span>

 

单性:(x)我们探烦我们能提供的最单的语言Q以及实玎ͼq样的)语言的最单的C代码。这意味着Q需要)不会(x)偏离传统很远的拥有很语al构的简单语法?/span>

 

效率Q我们探索编译和执行luaE序的最快方法,q就意味着Q需要)一个高效的、聪明的一遍扫描编译器和一个高效的虚拟机?/span>

 

可移植性:(x)我们希望lua能跑在尽可能多的q_上。我们希望能在Q何地方不用修改地~译lua核心Q在M一个带有合适的lua解释器的q_上不用修改地q行luaE序。这意味着一个对可移植性特别关注的q净?/span>ANSI C的实玎ͼ例如避开C和标准库库中的陷qPq确保能?/span>c++方式q净地编译。我们追?/span>warning-free的编译(实现Q?/span>

 

嵌入性:(x)lua是一门扩展语aQ它被设计用来ؓ(f)大型E序提供脚本设施。这个以及其他目标就意味着一个简单ƈ且强大的C API实现Q但q样更多地依赖内徏?/span>Ccd?/span>

 

嵌入的低成本Q我们希望能Ҏ(gu)地将Luadq一个应用,而不?x)应用变的臃肿。这意味着Q需要)紧凑?/span>C代码和一个小?/span>Lua核心Q扩展将作ؓ(f)用户库来d?/span>

 

q些目标是有所权衡的。例如,lual常被用作数据描q语aQ用于保存和加蝲文gQ有时是非常大的数据?/span>(?/span>M字节?/span>luaE序不常?/span>)。这意味着我们需要一个快速的lua~译器。另一斚wQ我们想?/span>luaE序q行快速,q就意味着Q需要)一个可以ؓ(f)虚拟Z生优U代码的聪明的~译器。因此,LUA~译器的实现必须在这两种需求中Lq。尽如此,~译器还是不能太大,否则整个发行包变的臃ѝ目前编译器大约?/span>lua核心大小?/span>30%。在内存受限的应用中Q比如嵌入式pȝQ嵌入不带有~译器的Lua是可能的Q?/span>LuaE序被ȝ预编译,然后被一个小模块Q这个小模块也是快速的Q因为它加蝲的是二进制文Ӟ在运行时加蝲?/span>

 

Lua使用了一个手写的扫描器和一个手写的递归下降解释器。直?/span>3.0版本Q?/span>luaq在使用一?/span>YACC产生的解释器Q这在语a的语法不够稳定的时候很有h(hun)值的。然而,手写的解释器更小、更高效、更M以及完全可重入,也能提供更好的出错信息(error messageQ?/span>

Lua~译器没有用中间代码表C(译注Q也是不生成中间代码)。当解释一个程序的时候,它以“on-the-fly”的方式给虚拟机发出指令。不q,它会(x)q行一些优化。例如,它会(x)推迟像变量和帔Rq样的基本表辑ּ的代码生成。当它解释这L(fng)表达式的时候,没有产生M代码Q而是使用一U简单的l构来表C它们。所以,判断一个给定指令的操作数是帔Rq是变量以及它们的值直接应用在指o都变的非常容易,避免了不必要的和昂贵的移动?/span>

ZM地在许许多多不同?/span>C~译器和q_之间ULQ?/span>Lua不能使用许多解释器通常使用的技巧,例如direct threaded code [8, 16]。作为替代,它(译注Q指lua解释器)使用了标准的while-switch分发循环。此处的C代码看v来过于复杂,但是复杂性也是ؓ(f)了确保可UL性。当lua在许多不同的q_上(包括64位^台和一?/span>16位^収ͼ被很多不同的C~译器编译,lua实现的可UL性一直以来变的越来越E_了?/span>

我们认ؓ(f)我们已经辑ֈ我们的设计和实现目标了?/span>Lua是一门非常轻便的语言Q它能跑在Q何一个带?/span>ANSI C~译器的q_上,从嵌入式pȝ到大型机?/span>Lua实是轻量的:(x)例如Q它?/span>linuxq_上的独立解释器包括所有的标准库,占用的空间小?/span>150K;核心更是于100K?/span>lua是高效的Q独立的基准试表明lua是脚本语aQ解释的、动态类型的语言Q领域中最快的语言之一。主观上我们也认?/span>lua是一门简单的语言Q语法上cMPascalQ语义上cMSchemeQ译注:(x)Lisp的一U方aQ?/span>

 

3、值的表示

Lua是动态类型语aQ类型依附于D不是变量?/span>Lua?/span>8U基本类型:(x)nil, boolean, number, string, table, function,userdata, ?/span>thread?/span>Nil是一个标记类型,它只拥有一个g?/span>nil?/span>Boolean是通常?/span>true?/span>false?/span>Number是双_ֺ点敎ͼ对应?/span>C语言中的doublecdQ但?/span>float或?/span>long作ؓ(f)替代来编?/span>lua也很Ҏ(gu)Q不游?/span>consoles或者小机器都缺乏对double的硬件支持)?/span>String是有昑ּ大小的字节数l,因此可以存储L的二q制cdQ包括嵌入零?/span>Tablecd是兌的数l,可以用Q何值做索引Q除?/span>nilQ,也可以持有Q何倹{?/span>Function是依据与lua虚拟接的协议~写?/span>lua函数或?/span>C函数?/span>Userdata本质上是指向用户内存区块Q?/span>user memory blockQ的指针Q有两种风格Q重量,?/span>lua分配块ƈ?/span>GC回收Q轻量Q由用户分配和释放(内存Q块。最后,thread表示coroutines。所有类型的值都?/span>first-class|(x)我们可以它们作为全局变量、局部变量和table的域来存储,作ؓ(f)参数传递给函数Q作为函数的q回值等{?/span>

 

typedef struct {                        typedef union {

int t;                                      GCObject *gc;

Value v;                                   void *p;

} TObject;                                 lua_Number n;

int b;

} Value;

Figure 1: 带标{union表示lua?/span>

 

 

LuaDCZؓ(f)带标{union(tagged unions)Q也是pairs(t,v)Q其?/span>t是一个决定了?/span>vcd的整数型标签Q?/span>v是一个实Cluacd?/span>C语言?/span>unionl构?/span>Nil拥有一个单独的|译注Q也是nilQ?/span>Booleans?/span>numbers被实Cؓ(f)“拆箱?#8221;的|(x)v?/span>union中直接表C些类型的倹{这意味着unionQ译注:(x)指图中的ValueQ必L_的空间容U?/span>doubleQ类型)?/span>Strings,tables, functions, threads, ?/span> userdatacd的值通过引用来实玎ͼ(x)v拥有指向实现q些cd的结构的指针。这些结构(译注Q指实现Strings,tables, functions, threads, ?/span> userdataq些cd的具体结构)׃n一个共同的headQ用来保存用于垃圾收集的信息。结构的剩下的部分专属于各自的类型?/span>

 Figure1展示了一个实际的lua值的实现?/span>TObject是这个实现的主要l构体:(x)它表CZ上文描述的带标签的联合体Q?/span>tagged unionsQ?/span> (t,v)?/span>Value是实C值的unioncd。类?/span>nil的值没有显式表C在q个unioncd中是因ؓ(f)标签已经_标识它们。域n用来表示numberscdQ?/span>lua_Number默认?/span>doublecdQ。同P?/span>b是给booleanscd用的Q域p是给轻量U的userdatacd。而域gc是ؓ(f)?x)被垃圾回收的其他类型准备的Q?/span>(strings, tables, functions, 重量U?/span>userdata, ?/span>threads)?/span>

 

使用带标{union实现lua值的一个后果就是拷贝值的代h(hun)E微昂贵了一点:(x)在一台支?/span>64?/span>doublecd?/span>32位机器上Q?/span>TObject的大是12字节Q或?/span>16字节Q如?/span>double?/span>8字节寚w的话Q,因此拯一个值将需要拷?/span>3Q或?/span>4Q个机器字长。尽如此,惛_ANSI C中实C个更好的值的表示是困隄。一些动态类型语aQ例?/span>Smalltalk80的原始实玎ͼ在每个指针中使用多余的位来存储值的cd标签。这个技巧在l大多数机器上正常工作,q是因ؓ(f)一个指针的最后两个或者三个位׃寚wL0Q所以可以被用作他途。但是,q项技术既不是可移植的也无法在ANSI C中实玎ͼC 语言标准甚至都不保证指针适合M整数cdQ所以没有在指针上操作位的标准方法?/span>

减小值大的另一个观点就是持有显式标{,从而避免在union中放|一?/span>doublecd。例如,所有的numbercd可以表示为堆分配的对象,像String那样。(python使用了这Ҏ(gu)术,除了预先分配了一些小的整数|。尽如此,q样的表C方法将使语a变的非常~慢。作为选择Q整数的值可以表CZ“拆箱?#8221;的|直接存储?/span>union中,而Q点值放在堆中。这个办法将极大地增加所有算术运操作的实现复杂度?/span>

cM早期的解释型语言Q例?/span>Snobol [11] ?/span> Icon [10]Q?/span>lua在一?/span>hash表中“拘留”(internalizes)字符Ԍ(x)Q?/span>hash表)没有重复地持有每个字W串的单独拷贝。此外,String是不可变的:(x)一个字W串一旦被“拘留”Q将不能再被改变。字W串的哈希g据一个؜合了位和术q算的简单表辑ּ来计,囊括所有的位。当字符串被“拘留”Ӟhashg存(?/span>hash表)Q以支持更快的字W串比较和表索引。如果字W串太长的话Q?/span>hash函数q不?x)用到字W串的所有字节,q有利于快速地散列长字W串。避免处理长字符串带来的性能损失是重要的Q因为(q样的操作)?/span>lua中是很普遍的。例如,?/span>lua处理文g的时候经常将整个文g内容作ؓ(f)一个单独的长字W串d内存?/span>



dennis 2008-04-07 17:25 发表评论
]]>
重定向和道的实?/title><link>http://www.aygfsteel.com/killme2008/archive/2008/02/29/182868.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 29 Feb 2008 03:16:00 GMT</pubDate><guid>http://www.aygfsteel.com/killme2008/archive/2008/02/29/182868.html</guid><wfw:comment>http://www.aygfsteel.com/killme2008/comments/182868.html</wfw:comment><comments>http://www.aygfsteel.com/killme2008/archive/2008/02/29/182868.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/killme2008/comments/commentRss/182868.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/killme2008/services/trackbacks/182868.html</trackback:ping><description><![CDATA[重定向标准输入的实现Q?br /> 1Qclose-then-open: close(0) ; fd=open("test",O_RDONLY); fd是stdin?br /> 2)open-close-dup-close:<br /> fd=open(file),打开stdin要重定向的文gQclose(0);new_fd=dup(file);close(fd);new_fd是被重定向的stdin<br /> 3)open-dup2-close:<br /> fd=open(file);new_fd=dup2(fd,0);close(fd);<br /> <br /> 重定向标准输出的实现Q?br />   父进Efork();子进Eclose(1);create("g",0644)Q此时子q程的stdout被重定向到g;接下来子q程exec某个E序Q文件描q符属于q程属性,exec调用不会(x)改变他们Q那么运行的E序的标准输出将被送到gQ由此实C标准输出重定向?br /> <br /> 本质上重定向的实现是依赖两个原则Q?br /> 1、标准输入、标准输出和标准错误分别???<br /> 2、最低可用描q符Q打开文gӞ为此文g安排的描q符Lq程内打开文g数组的最低可用位|的索引?br /> <br /> 道Q?br />   匿名道Q适合于有亲缘关系的进E,通过pipe函数实现?br />   有名道Q通过mkfifo函数实现Q实现进E间的双向通讯可以采用两个有名道实现Q也可以采用socketpair调用?img src ="http://www.aygfsteel.com/killme2008/aggbug/182868.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/killme2008/" target="_blank">dennis</a> 2008-02-29 11:16 <a href="http://www.aygfsteel.com/killme2008/archive/2008/02/29/182868.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>写操作系l?看看q个Q{载)http://www.aygfsteel.com/killme2008/archive/2008/02/22/181476.htmldennisdennisFri, 22 Feb 2008 09:53:00 GMThttp://www.aygfsteel.com/killme2008/archive/2008/02/22/181476.htmlhttp://www.aygfsteel.com/killme2008/comments/181476.htmlhttp://www.aygfsteel.com/killme2008/archive/2008/02/22/181476.html#Feedback3http://www.aygfsteel.com/killme2008/comments/commentRss/181476.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/181476.html《免费电(sh)子书<使用开源Y件——自己动手写操作pȝ>?
    只能说太酷了Qchina-pub上一直有本书《自己动手写操作pȝ》,牛h看到q本书用的是商业Y件做CQ于是动忉|是不是能使用开源Y件来实现书中所有的demoQ于是就有了q本宝贵的电(sh)子书?br />     目主页Qhttp://share.solrex.cn/WriteOS/




dennis 2008-02-22 17:53 发表评论
]]>
视频站点的搭?/title><link>http://www.aygfsteel.com/killme2008/archive/2007/12/19/168788.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Wed, 19 Dec 2007 08:46:00 GMT</pubDate><guid>http://www.aygfsteel.com/killme2008/archive/2007/12/19/168788.html</guid><wfw:comment>http://www.aygfsteel.com/killme2008/comments/168788.html</wfw:comment><comments>http://www.aygfsteel.com/killme2008/archive/2007/12/19/168788.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/killme2008/comments/commentRss/168788.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/killme2008/services/trackbacks/168788.html</trackback:ping><description><![CDATA[    Z没动W写blog了,换了新工作比较忙是一个原因。最q的工作是做一个素材管理的pȝQ其中有个要求做视频预览Q将用户上传的视频{换ƈ在网上预览。在|页上看视频Q现在大多数视频|站都是采用flv媒体文Ӟ用flash做的播放器播放,我们也采用了q种方式。流E大概主要:(x)用户上传文g->后台转换文g成flv格式->flv播放器调用flv文g?br />     转换视频、音频文件到flv格式可以使用mencoder或者f(xi)fmpegQ我们采用了mencoderQ在linux上的安装参?a >q里</a>,安装l束后记的设|环境变量:(x)export LD_LIBRARY_PATH=/usr/local/lib:LD_LIBRARY_PATH<br />     java调用的话是通过ProcessQ?br /> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 0);"> Process process </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> runtime.exec(cmd);</span></div> <br /> mencoder转换视频音频成flv命oQ?br /> mencoder 源文?-o 目标文g.flv -of lavf    -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=400:mbd=2:mv0:trell:v4mv:cbp:last_pred=3:dia=4:cmp=6:vb_strategy=1 -vf scale=200:-3 -ofps 12 -srate 22050<br /> <br /> 取视频元信息命oQ视频比特率、长宽等信息Q:(x)<br /> mplayer -identify 文g?-ao null -vo null -frames 0 <br /> <br /> 切割视频命oQ?br /> mencoder -ss 开始时?-oac copy -ovc copy -endpos l止旉 文g?-o 目标文g?br /> <br />     操作flv文gQ给视频打上信息、切割之c)可以采用<a >flvtool2</a>?br />     <br />     需要注意的是通过java调用的话Q一定要处理标准输出和标准错误输出,不然q程?x)挂在那l束不了Q可以开个线E取处理。在|页播放的话Q可以考虑?a >q个播放?/a>Q具体参数看它的说明。最后一个问题,IE6的flash控g需要激z,q个问题的解军_以采?a >swfobject.js</a>?br />     有兴的老大们可以考虑自己搭个“土豆|?#8221;Q说不定哪天拿了风投.....云<br /><img src ="http://www.aygfsteel.com/killme2008/aggbug/168788.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/killme2008/" target="_blank">dennis</a> 2007-12-19 16:46 <a href="http://www.aygfsteel.com/killme2008/archive/2007/12/19/168788.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>今天长见识了http://www.aygfsteel.com/killme2008/archive/2007/11/29/164069.htmldennisdennisThu, 29 Nov 2007 10:17:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/11/29/164069.htmlhttp://www.aygfsteel.com/killme2008/comments/164069.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/11/29/164069.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/164069.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/164069.htmlcoroutineQ然后去google coroutineQ找?/span>Simon Tatham写的一?/span>coroutine in cQ讲怎么在C语言中实?/span>coroutineQ文?/span>先ugly地基于栈实现了一个:(x)
int function(void) {
    
static int i, state = 0;
    
switch (state) {
        
case 0goto LABEL0;
        
case 1goto LABEL1;
    }
    LABEL0: 
/* start of function */
    
for (i = 0; i < 10; i++) {
        state 
= 1/* so we will come back to LABEL1 */
        
return i;
        LABEL1:; 
/* resume control straight after the return */
    }
}

q个Ҏ(gu)单,但是相当丑陋Q你必须手工l护q些标签。然后提CDuff's Device技巧:(x)
switch (count % 8) {
        
case 0:        do {  *to = *from++;
        
case 7:              *to = *from++;
        
case 6:              *to = *from++;
        
case 5:              *to = *from++;
        
case 4:              *to = *from++;
        
case 3:              *to = *from++;
        
case 2:              *to = *from++;
        
case 1:              *to = *from++;
                       } 
while ((count -= 8> 0);
    }

q段代码能编译通过吗?能的Q不信你试试Q这是一D는于拷贝数l的代码Q我们一般拷贝数l是q样做的Q?br />
send(to, from, count)
        register 
short *to, *from;
        register count;
        {
                
do
                        
*to = *from++;
                
while(--count>0);
        }
如果循环的中的操作够快Q那么其实大部分旉都是费在判断@环条件上面的Q而通过Duff's Device通过switch语句要q行的连l@环操作的ơ数q行了预判(Ҏ(gu)擦case语句的位|)然后依次执行Q而不必每ơ都去进 行测试条Ӟ从而加速@环。这个技巧怎么应用于实现更优雅?span style="font-size: 10.5pt; font-family: "Times New Roman";" lang="EN-US">coroutine呢?看代?br />
int function(void) {
    
static int i, state = 0;
    
switch (state) {
        
case 0/* start of function */
        
for (i = 0; i < 10; i++) {
            state 
= 1/* so we will come back to "case 1" */
            
return i;
            
case 1:; /* resume control straight after the return */
        }
    }
}
更好的方式是使用宏:(x)
#define crBegin static int state=0; switch(state) { case 0:
#define crReturn(i,x) do { state=i; return x; case i:; } while (0)
#define crFinish }
int function(void) {
    
static int i;
    crBegin;
    
for (i = 0; i < 10; i++)
        crReturn(
1, i);
    crFinish;
}





dennis 2007-11-29 18:17 发表评论
]]>
hack,hackerhttp://www.aygfsteel.com/killme2008/archive/2007/10/15/152846.htmldennisdennisMon, 15 Oct 2007 01:09:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/10/15/152846.htmlhttp://www.aygfsteel.com/killme2008/comments/152846.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/10/15/152846.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/152846.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/152846.htmlmongrel_light_cluster的过E中Q发现这个clusterq反了copy-on-write的语义,D占用了太多的内存。根本原因在于Ruby的GC机制?a >marks all memory pages as dirty。ؓ(f)了减内存的占用Q让集群跑更多mongrelQ牛上了hack之\Q给c ruby打补丁,他也真的做到?/a>。c ruby的GC使用的是mark and sweep(标记q清?的垃圾收集算法,他发现在markq程中用了st_tableQ这个数据结构占用了很大的内存,那么改?a >Google’s sparse_hash。然后他又写了一个memory poolQ以应对marking和sweep使用q程中对malloc和free调用带来的内存损失,因ؓ(f)在x86 GNU/linux gcc上,malloc函数如果甌的内存小?6KBQ那么当free的时候这些内存不?x)被q还l操作系l。他的hack之\q没l束Q有兴趣的关注他的blog:

 http://izumi.plan99.net/blog/index.php/




dennis 2007-10-15 09:09 发表评论
]]>
Ruby变量在c ruby中的存储http://www.aygfsteel.com/killme2008/archive/2007/09/20/146799.htmldennisdennisThu, 20 Sep 2007 08:17:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/09/20/146799.htmlhttp://www.aygfsteel.com/killme2008/comments/146799.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/09/20/146799.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/146799.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/146799.html 1.在Ruby中,cM是一个对象,因此有实例变量。类的实例变量、类变量、常量都是存储在RClass struct的iv_tbl中,
struct RClass {
    struct RBasic basic;
    struct st_table *iv_tbl;
    struct st_table *m_tbl;
    VALUE super;
};
iv_tbl的类型是st_tableQ我?a href="http://www.aygfsteel.com/killme2008/archive/2007/09/18/146234.html">q里用java实现了一下?br />
2.用户自定义类的对象(ruby层次声明的类的对?的实例变量存储在RObject struct的iv_tbl中,
struct RObject {
  struct RBasic basic;
  struct st_table *iv_tbl;
 };
调用Ҏ(gu)Q本质上是一个查表操作。buildin的几个类Q比如String、Array、Hash{?在c层次上实现的c)Q它们的l构q没有iv_tableQ这是从节省内存I间的角度考虑Q它们的实例变量存储在一张全局的st_table中。这张表比较特别Q其中的每一个对应的值又是一个st_tableQ也是一?#8220;二元l构”Q第一层结构是cd与实例变量表的映,W二层才是实例变量名与实际值的映射?br />
3.全局变量存储在一张全局的st_table中,q个表的键就是变量名IDQ由于全局变量允许通过alias来设|别名,因此q张全局表中真正存储的是下面q个struct

334 struct global_entry {
335 struct global_variable *var;
336 ID id;
337 };

324 struct global_variable {
325 int counter; /* 引用计数 */
326 void *data; /* 变量?*/
327 VALUE (*getter)(); /* 取值函?*/
328 void (*setter)(); /* 讄函数 */
329 void (*marker)(); /* 标记函数 */
330 int block_trace;
331 struct trace_var *trace;
332 };
(variable.c)

当不同变量名Q通过别名声明Q指向的是同一个全局变量Q其实它们指向的是同一个struct global_variable?br />



dennis 2007-09-20 16:17 发表评论
]]>
判断栈的增长方向http://www.aygfsteel.com/killme2008/archive/2007/09/17/145892.htmldennisdennisMon, 17 Sep 2007 08:16:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/09/17/145892.htmlhttp://www.aygfsteel.com/killme2008/comments/145892.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/09/17/145892.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/145892.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/145892.html栈的增长方向》。今天在读Ruby hacking guideW?章,介绍alloca函数的部分,提到ruby实现的C语言版本的alloca.cQ读了下代码Q发现这里倒是实现了一个很漂亮的函数用于实现判断栈的增长方向,利用了局部static变量Q与dreamhead老大的想法其实是一致的?br />
#include<stdio.h>
static void find_stack_direction(void);
static int stack_dir;
int main(void)
{
  find_stack_direction();
  
if(stack_dir==1)
     puts(
"stack grew upward");
  
else
     puts(
"stack grew downward");
  
return 0;
}
static void find_stack_direction (void)
{
  
static char   *addr = NULL;   /* address of first
                                   `dummy', once known 
*/
  auto 
char     dummy;          /* to get stack address */

  
if (addr == NULL)
    {                           
/* initial entry */
      addr 
= &dummy;

      find_stack_direction ();  
/* recurse once */
    }
  
else                          /* second entry */
    
if (&dummy > addr)
      stack_dir 
= 1;            /* stack grew upward */
    
else
      stack_dir 
= -1;           /* stack grew downward */
}



dennis 2007-09-17 16:16 发表评论
]]>
C语言中实现可变参数函?/title><link>http://www.aygfsteel.com/killme2008/archive/2007/08/31/141775.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 31 Aug 2007 09:06:00 GMT</pubDate><guid>http://www.aygfsteel.com/killme2008/archive/2007/08/31/141775.html</guid><wfw:comment>http://www.aygfsteel.com/killme2008/comments/141775.html</wfw:comment><comments>http://www.aygfsteel.com/killme2008/archive/2007/08/31/141775.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/killme2008/comments/commentRss/141775.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/killme2008/services/trackbacks/141775.html</trackback:ping><description><![CDATA[    通过stdarg.h头文件ؓ(f)函数提供了定义可变参数列表的能力。声明一个可变参数的函数cMQ?br /> void f1(int n,...);<br /> <br /> 其中n表示参数列表个数Q而用省略h表示未知参数列表。stdarg.h中提供了一个va_listcdQ用于存攑֏数。一个大概的使用q程cMQ?br /> void f1(int n,...)<br /> {<br />    va_list ap;<br />    va_start(ap,n);   //初始化参数列?br />    double first=va_arg(ap,double);  //取第一个参?br />    int second=va_arg(ap,int);   //取第二个参数<br />    ...<br />    va_end(ap);  //清理工作<br /> }<br /> 看一个求和的例子Q?br /> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000;">#include</span><span style="color: #000000;"><</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> #include</span><span style="color: #000000;"><</span><span style="color: #000000;">stdarg.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #0000ff;">double</span><span style="color: #000000;"> sum(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> ,<img src="http://www.aygfsteel.com/Images/dot.gif" alt="" />);<br /> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> main(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">)<br /> {<br />   </span><span style="color: #0000ff;">double</span><span style="color: #000000;"> s,t;<br />   s</span><span style="color: #000000;">=</span><span style="color: #000000;">sum(</span><span style="color: #000000;">3</span><span style="color: #000000;">,</span><span style="color: #000000;">1.1</span><span style="color: #000000;">,</span><span style="color: #000000;">2.2</span><span style="color: #000000;">,</span><span style="color: #000000;">13.3</span><span style="color: #000000;">);<br />   t</span><span style="color: #000000;">=</span><span style="color: #000000;">sum(</span><span style="color: #000000;">6</span><span style="color: #000000;">,</span><span style="color: #000000;">1.1</span><span style="color: #000000;">,</span><span style="color: #000000;">2.1</span><span style="color: #000000;">,</span><span style="color: #000000;">13.1</span><span style="color: #000000;">,</span><span style="color: #000000;">4.1</span><span style="color: #000000;">,</span><span style="color: #000000;">5.1</span><span style="color: #000000;">,</span><span style="color: #000000;">6.1</span><span style="color: #000000;">);<br />   printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">return value for </span><span style="color: #000000;">"</span><span style="color: #000000;">  \<br />     </span><span style="color: #000000;">"</span><span style="color: #000000;">sum(3,1.1,2.2,13.3):   %g\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,s);<br />   printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">return value for </span><span style="color: #000000;">"</span><span style="color: #000000;"> \<br />     </span><span style="color: #000000;">"</span><span style="color: #000000;">sum(6,1.1,2.1,13.1,4.1,5.1,6.1):    %g\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,t);<br />   </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">;<br /> }<br /> </span><span style="color: #0000ff;">double</span><span style="color: #000000;"> sum(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> lim,<img src="http://www.aygfsteel.com/Images/dot.gif" alt="" />)<br /> {<br />   va_list ap;<br />   </span><span style="color: #0000ff;">double</span><span style="color: #000000;"> total</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />   va_start(ap,lim);<br />   </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> i;<br />   </span><span style="color: #0000ff;">for</span><span style="color: #000000;">(i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;i</span><span style="color: #000000;"><</span><span style="color: #000000;">lim;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />       total</span><span style="color: #000000;">+=</span><span style="color: #000000;">va_arg(ap,</span><span style="color: #0000ff;">double</span><span style="color: #000000;">);<br />   va_end(ap);<br />   </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> total;<br /> }<br /> </span></div> <br /> C语言对可变参数的使用q是有点ȝQ不如ruby和javaѝ比如ruby中定义ƈ使用可变参数参数Q?br /> def sum(*e)<br />    e.inject{|sum,i| sum+=i}<br /> end<br /> <br /> sum(1,2,3,4,5)=>15<br />    <br /> <br /><img src ="http://www.aygfsteel.com/killme2008/aggbug/141775.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/killme2008/" target="_blank">dennis</a> 2007-08-31 17:06 <a href="http://www.aygfsteel.com/killme2008/archive/2007/08/31/141775.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>断开的管道?http://www.aygfsteel.com/killme2008/archive/2007/08/29/141062.htmldennisdennisWed, 29 Aug 2007 11:17:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/08/29/141062.htmlhttp://www.aygfsteel.com/killme2008/comments/141062.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/08/29/141062.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/141062.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/141062.html
#include<signal.h>
....

signal(SIGPIPE, SIG_IGN);




dennis 2007-08-29 19:17 发表评论
]]>
比较C语言标准I/O?nixpȝI/O的异?/title><link>http://www.aygfsteel.com/killme2008/archive/2007/08/22/138651.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Wed, 22 Aug 2007 08:47:00 GMT</pubDate><guid>http://www.aygfsteel.com/killme2008/archive/2007/08/22/138651.html</guid><wfw:comment>http://www.aygfsteel.com/killme2008/comments/138651.html</wfw:comment><comments>http://www.aygfsteel.com/killme2008/archive/2007/08/22/138651.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/killme2008/comments/commentRss/138651.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/killme2008/services/trackbacks/138651.html</trackback:ping><description><![CDATA[    linux/unixpȝ的I/O也就是一般所说的低I/O——操作系l提供的基本IO服务Q与osl定Q特定于*nixq_。而标准I/O是ANSI C建立的一个标准I/O模型Q是一个标准函数包和stdio.h头文件中的定义,h一定的可移植性。两者一个显著的不同点在于,标准I/O默认采用了缓冲机Ӟ比如调用fopen函数Q不仅打开一个文Ӟ而且建立了一个缓冲区Q读写模式下徏立两个缓冲区Q,q创Z一个包含文件和~冲区相x据的数据l构。低UI/O一般没有采用缓Ԍ需要自己创建缓冲区Q不q其实在*nixpȝ中,都是有用称?span style="font-weight: bold;">内核~冲</span>的技术用于提高效率,d调用是在内核~冲区和q程~冲Z间进行的数据复制?br><br><span style="font-weight: bold;">1.fopen与open</span><br><span style="font-weight: bold;">标准I/O使用fopen函数打开一个文?/span>Q?br>FILE* fp=fopen(const char* path,const char *mod)<br><br>其中path是文件名Qmod用于指定文g打开的模式的字符Ԍ比如"r","w","w+","a"{等Q可以加上字母b用以指定以二q制模式打开Q对?nixpȝQ只有一U文件类型,因此没有区别Q?如果成功打开Q返回一个FILE文g指针Q如果失败返回NULL,q里的文件指针ƈ不是指向实际的文Ӟ而是一个关于文件信息的数据包,其中包括文g使用的缓冲区信息?br><br><span style="font-weight: bold;">*nixpȝ使用open函数用于打开一个文?/span>Q?br>int fd=open(char *name,int how);<br>与fopencMQname表示文g名字W串Q而how指定打开的模式:(x)O_RDONLY(只读),O_WRONLY(只写Q?O_RDWR Q可d?,q有其他模式请man 2 open。成功返回一个正整数UCؓ(f)<span style="font-weight: bold;">文g描述W?/span>Q这与标准I/O显著不同Q失败的话返?1Q与标准I/Oq回NULL也是不同的?br><br><span style="font-weight: bold;">2.fclose与close</span><br>与打开文g相对的,<span style="font-weight: bold;">标准I/O使用fclose关闭文g</span>Q将文g指针传入卛_Q如果成功关闭,q回0Q否则返回EOF<br>比如Q?<br><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;"></span> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">if</span><span style="color: #000000;">(fclose(fp)</span><span style="color: #000000;">!=</span><span style="color: #000000;">0</span><span style="color: #000000;">)  <br>  printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Error in closing file</span><span style="color: #000000;">"</span><span style="color: #000000;">);</span></div> <br>?nix使用close用于关闭open打开的文Ӟ与fclosecMQ只不过当错误发生时q回的是-1Q而不是EOFQ成功关闭同hq回0。C语言用error code来进行错误处理的传统做法?br><br><span style="font-weight: bold;">3.L?/span>Qgetc,fscanf,fgets和read<br>标准I/O中进行文件读取可以用getcQ一个字W一个字W的dQ也可以使用getsQ读取标准iod的)、fgets以字W串单位q行dQ读到遇到的W一个换行字W的后面Q,getsQ接受一个参敎ͼ文g指针Q不判断目标数组是否能够容纳d的字W,可能D存储溢出(<span style="font-weight: bold;">不徏议?/span>Q,而fgets使用三个参数Q?br> char * fgets(char *s, int size, FILE *stream); <br>W一个参数和gets一P用于存储输入的地址Q第二个参数为整敎ͼ表示输入字符串的最大长度,最后一个参数就是文件指针,指向要读取的文g。最后是fscanfQ与scanfcMQ只不过增加了一个参数用于指定操作的文gQ比如fscanf(fp,"%s",words)<br><br>*nixpȝ中用read函数用于dopen函数打开的文Ӟ函数原型如下Q?br>ssize_t numread=read(int fd,void *buf,size_t qty);<br><br>其中fd是openq回的文件描q符Qbuf用于存储数据的目的缓冲区Q而qty指定要读取的字节数。如果成功读取,p回读取的字节数目Q小于等于qtyQ?br><br><span style="font-weight: bold;">4.判断文gl尾</span>Q如果尝试读取达到文件结,标准IO的getc?x)返回特D值EOFQ而fgets到EOF?x)返回NULL,而对?nix的read函数Q情冉|所不同。readdqty指定的字节数Q最l读取的数据可能没有你所要求的那么多QqtyQ,而当dl尾再要ȝ话,read函数返?.<br><br><span style="font-weight: bold;">5.写文?/span>Qputc,fputs,fprintf和write<br><br>与读文g相对应的Q标准C语言I/O使用putc写入字符Q比如:(x)<br>putc(ch,fp);<br>W一个参数是字符Q第二个是文件指针。而fputs与此cMQ?br>fputs(buf,fp);<br>仅仅是第一个参数换成了字符串地址。而fprintf与printfcMQ增加了一个参数用于指定写入的文gQ比如:(x)<br>fprintf(stdout,"Hello %s.\n","dennis");<br>切记fscanf和fprintfFILE指针作ؓ(f)W一个参敎ͼ而putc,fputs则是作ؓ(f)W二个参数?br><br>?nixpȝ中提供write函数用于写入文gQ原型与readcMQ?br>ssize_t result=write(int fd,void *buf ,size_t amt);<br><br>fd是文件描q符Qbuf是将要写入的内存数据Qamt是要写的字节数。如果写入成功返回写入的字节敎ͼ通过result与amt的比较可以判断是否写入正常,如果写入p|q回-1。write函数仅仅是将数据写入了缓冲区Q何时写入磁盘由内核军_Q如果要强制写入盘Q那么在open的时候选择O_SYNC选项Q或者调用fsync函数<br><br><span style="font-weight: bold;">6.随机存取</span>Qfseek()、ftell()和lseek()<br>标准I/O使用fseek和ftell用于文g的随机存取,先看看fseek函数原型<br>int fseek(FILE *stream, long offset, int whence);<br>W一个参数是文g指针Q第二个参数是一个longcd的偏U量QoffsetQ,表示从v始点开始移动的距离。第三个参数是用于指定起始点的模式Qstdio.h指定了下列模式常量:(x)<br>SEEK_SET            文g开始处<br>SEEK_CUR            当前位置<br>SEEK_END            文gl尾?br>看几个调用例子:(x)<br>fseek(fp,0L,SEEK_SET);  //扑ֈ文g的开始处<br>fseek(fp,0L,SEEK_END);  //定位到文件结֤<br>fseek(fp,2L,SEEK_CUR);  //文g当前位置向前Ud2个字节数<br><br>而ftell函数用于q回文g的当前位|,q回cd是一个longcdQ比如下面的调用Q?br>fseek(fp,0L,SEEK_END);//定位到结?br>long last=ftell(fp);  //q回当前位置<br>那么此时的last是文g指针fp指向的文件的字节数?br><br>与标准I/OcMQ?nixpȝ提供了lseek来完成fseek的功能,原型如下Q?br>off_t lseek(int fildes, off_t offset, int whence); <br><br>fildes是文件描q符Q而offset也是偏移量,whence同样是指定v始点模式Q唯一的不同是lseek有返回|如果成功p回指针变化前的位|,否则q回-1。因此可以通过下列Ҏ(gu)模拟ftell函数来返回当前偏U量Q?br>off_t    currpos;<br>currpos = lseek(fd, 0, SEEK_CUR); <br>whence的取gfseek相同QSEEK_SET,SEEK_CUR,SEEK_ENDQ但也可以用整数0,1,2相应代替?br><br>最后,以一个例子结,通过c语言~写linuxpȝ的cp指oQ先看看使用标准I/O版本的:(x)<br> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include</span><span style="color: #000000;"><</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br>#include</span><span style="color: #000000;"><</span><span style="color: #000000;">stdlib.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;"> oops(</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">,</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">);<br></span><span style="color: #0000ff;">int</span><span style="color: #000000;"> main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> ac,</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">av[])<br>{<br>  FILE </span><span style="color: #000000;">*</span><span style="color: #000000;">in,</span><span style="color: #000000;">*</span><span style="color: #000000;">out;<br>  </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> ch;<br><br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(ac</span><span style="color: #000000;">!=</span><span style="color: #000000;">3</span><span style="color: #000000;">){<br>   fprintf(stderr,</span><span style="color: #000000;">"</span><span style="color: #000000;">Useage:%s source-file target-file.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,av[</span><span style="color: #000000;">0</span><span style="color: #000000;">]);<br>   exit(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br>  }<br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">((in</span><span style="color: #000000;">=</span><span style="color: #000000;">fopen(av[</span><span style="color: #000000;">1</span><span style="color: #000000;">],</span><span style="color: #000000;">"</span><span style="color: #000000;">r</span><span style="color: #000000;">"</span><span style="color: #000000;">))</span><span style="color: #000000;">==</span><span style="color: #000000;">NULL)<br>   oops(</span><span style="color: #000000;">"</span><span style="color: #000000;">can not open </span><span style="color: #000000;">"</span><span style="color: #000000;">,av[</span><span style="color: #000000;">1</span><span style="color: #000000;">]);<br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">((out</span><span style="color: #000000;">=</span><span style="color: #000000;">fopen(av[</span><span style="color: #000000;">2</span><span style="color: #000000;">],</span><span style="color: #000000;">"</span><span style="color: #000000;">w</span><span style="color: #000000;">"</span><span style="color: #000000;">))</span><span style="color: #000000;">==</span><span style="color: #000000;">NULL)<br>   oops(</span><span style="color: #000000;">"</span><span style="color: #000000;">can not open </span><span style="color: #000000;">"</span><span style="color: #000000;">,av[</span><span style="color: #000000;">2</span><span style="color: #000000;">]);<br>  </span><span style="color: #0000ff;">while</span><span style="color: #000000;">((ch</span><span style="color: #000000;">=</span><span style="color: #000000;">getc(in))</span><span style="color: #000000;">!=</span><span style="color: #000000;">EOF)<br>    putc(ch,out);<br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(fclose(in)</span><span style="color: #000000;">!=</span><span style="color: #000000;">0</span><span style="color: #000000;">||</span><span style="color: #000000;">fclose(out)</span><span style="color: #000000;">!=</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br>    oops(</span><span style="color: #000000;">"</span><span style="color: #000000;">can not close files.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;"> </span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>  </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;"> oops(</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">s1,</span><span style="color: #0000ff;">char</span><span style="color: #000000;">*</span><span style="color: #000000;"> s2)<br>{<br>  fprintf(stderr,</span><span style="color: #000000;">"</span><span style="color: #000000;">Error:%s %s\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,s1,s2);<br>  exit(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br>}<br></span></div> <br>再看一个用unix io的版本:(x)<br> <div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">#include</span><span style="color: #000000;"><</span><span style="color: #000000;">unistd.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br>#include</span><span style="color: #000000;"><</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br>#include</span><span style="color: #000000;"><</span><span style="color: #000000;">fcntl.h</span><span style="color: #000000;">></span><span style="color: #000000;"><br><br>#define BUFFERSIZE </span><span style="color: #000000;">4096</span><span style="color: #000000;"><br>#define COPYMODE </span><span style="color: #000000;">0644</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">void</span><span style="color: #000000;"> oops(</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">,</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">);<br><br></span><span style="color: #0000ff;">int</span><span style="color: #000000;"> main(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> ac,</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">av[])<br>{<br>  </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> in_fd,out_fd,n_chars;<br>  </span><span style="color: #0000ff;">char</span><span style="color: #000000;"> buf[BUFFERSIZE];<br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(ac</span><span style="color: #000000;">!=</span><span style="color: #000000;">3</span><span style="color: #000000;">){<br>    fprintf(stderr,</span><span style="color: #000000;">"</span><span style="color: #000000;">useage:%s source-file target-file.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,av[</span><span style="color: #000000;">0</span><span style="color: #000000;">]);<br>    exit(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br>  }<br><br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">((in_fd</span><span style="color: #000000;">=</span><span style="color: #000000;">open(av[</span><span style="color: #000000;">1</span><span style="color: #000000;">],O_RDONLY))</span><span style="color: #000000;">==-</span><span style="color: #000000;">1</span><span style="color: #000000;">)<br>     oops(</span><span style="color: #000000;">"</span><span style="color: #000000;">Can't open </span><span style="color: #000000;">"</span><span style="color: #000000;">,av[</span><span style="color: #000000;">1</span><span style="color: #000000;">]);<br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">((out_fd</span><span style="color: #000000;">=</span><span style="color: #000000;">creat(av[</span><span style="color: #000000;">2</span><span style="color: #000000;">],COPYMODE))</span><span style="color: #000000;">==-</span><span style="color: #000000;">1</span><span style="color: #000000;">)<br>    oops(</span><span style="color: #000000;">"</span><span style="color: #000000;">Can't open </span><span style="color: #000000;">"</span><span style="color: #000000;">,av[</span><span style="color: #000000;">2</span><span style="color: #000000;">]);<br>  </span><span style="color: #0000ff;">while</span><span style="color: #000000;">((n_chars</span><span style="color: #000000;">=</span><span style="color: #000000;">read(in_fd,buf,BUFFERSIZE))</span><span style="color: #000000;">></span><span style="color: #000000;">0</span><span style="color: #000000;">)<br>      </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(write(out_fd,buf,n_chars)</span><span style="color: #000000;">!=</span><span style="color: #000000;">n_chars)<br>           oops(</span><span style="color: #000000;">"</span><span style="color: #000000;">Write error to </span><span style="color: #000000;">"</span><span style="color: #000000;">,av[</span><span style="color: #000000;">2</span><span style="color: #000000;">]);<br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(n_chars</span><span style="color: #000000;">==-</span><span style="color: #000000;">1</span><span style="color: #000000;">)<br>      oops(</span><span style="color: #000000;">"</span><span style="color: #000000;">Read error from </span><span style="color: #000000;">"</span><span style="color: #000000;">,av[</span><span style="color: #000000;">1</span><span style="color: #000000;">]);<br>  </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(close(in_fd)</span><span style="color: #000000;">==-</span><span style="color: #000000;">1</span><span style="color: #000000;">||</span><span style="color: #000000;">close(out_fd)</span><span style="color: #000000;">==-</span><span style="color: #000000;">1</span><span style="color: #000000;">)<br>    oops(</span><span style="color: #000000;">"</span><span style="color: #000000;">Error closing files</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">""</span><span style="color: #000000;">);<br>  </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">;<br>}<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;"> oops(</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">s1,</span><span style="color: #0000ff;">char</span><span style="color: #000000;"> </span><span style="color: #000000;">*</span><span style="color: #000000;">s2)<br>{<br>  fprintf(stderr,</span><span style="color: #000000;">"</span><span style="color: #000000;">Error:%s</span><span style="color: #000000;">"</span><span style="color: #000000;">,s1);<br>  perror(s2);<br>  exit(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br>}<br></span></div> <br>昄Q在使用unix i/o的时候,你要更多地关注缓冲问题以提高效率Q而stdio则不需要考虑?br><br><br><br> <br><br><br><img src ="http://www.aygfsteel.com/killme2008/aggbug/138651.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/killme2008/" target="_blank">dennis</a> 2007-08-22 16:47 <a href="http://www.aygfsteel.com/killme2008/archive/2007/08/22/138651.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言?U存储类以及关键字volatile、restricthttp://www.aygfsteel.com/killme2008/archive/2007/08/04/134399.htmldennisdennisSat, 04 Aug 2007 07:34:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/08/04/134399.htmlhttp://www.aygfsteel.com/killme2008/comments/134399.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/08/04/134399.html#Feedback1http://www.aygfsteel.com/killme2008/comments/commentRss/134399.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/134399.htmlC?U存储类Q?br>自动——在一个代码块内(或在一个函数头部作为参量)声明的变量,无论有没有存储类修饰WautonQ都属于自动存储cR该cd有自动存储时期、代码块的作用域和空链接(no linkage),如未初始化,它的值是不确定的Qjava要求局部变量必d始化Q?br>
寄存?/span>——在一个代码块内(或在一个函数头部作为参量)使用修饰Wregister声明的变量属于寄存器存储cR该cM自动存储cȝ|h自动存储时期、代码块作用域和I接,声明为register仅仅是一个请求,而非命oQ因此变量仍然可能是普通的自动变量Q但是仍然无法获取地址。。如果没有被初始化,它的g是未定的?br>
静态、空链接——在一个代码块内用存储类修饰Wstatic声明的局部变量属于静态空q接存储cR该cd有静态存储时期、代码块作用域和I链接,仅在~译时初始化一ơ。如未明初始化Q它的字节将被设定ؓ(f)0.

静态、外部链?/span>——在所有函数外部定义、未使用static修饰的变量属于静态、外部链接存储类。改cd有静态存储时期、文件作用域和外部链接,仅在~译时初始化一ơ。如未明初始化Q它的字节也被设定ؓ(f)0.

静态、内部链?/span>——与静态、外部链接存储类不同的是Q它使用static声明Q也定义在所有函数外部,但是h内部链接Q仅能被与它在同一个文件的函数使用Q,仅在~译时初始化一ơ。如未明初始化Q它的字节也被设定ؓ(f)0.

两个关键字:(x)volatile和restrictQ两者都是ؓ(f)了方便编译器的优化?br>
volatile告诉~译器该被变量除了可被程序修Ҏ(gu)外还可能被其他代理修改,因此Q当要求使用volatile 声明的变量的值的时候,pȝL重新从它所在的内存d数据Q而不是用寄存器中的~存。比?br>val1=x;
val2=x;
如果没有声明volatileQ系l在lval2赋值的时候可能直接从寄存器读取xQ假定聪明的~译器优化了Q,而不是从内存的初始位|,那么在两ơ赋g_x完全有可能被被某些编译器未知的因素更改(比如Q操作系l、硬件或者其它线E等Q。如果声明ؓ(f)volatileQ编译器不使用~存Q而是每次都从内存重新dx?br>
而restrict是c99引入的,它只可以用于限定指针Qƈ表明指针是访问一个数据对象的唯一且初始的方式Q考虑下面的例子:(x)
int ar[10];
int * restrict restar=(int *)malloc(10*sizeof(int));
int *par=ar;

q里说明restar是访问由malloc()分配的内存的唯一且初始的方式。par׃是了?br>那么Q?br>for(n=0;n<10;n++)
{
   par[n]+=5;
   restar[n]+=5;
   ar[n]*=2;
   par[n]+=3;
   restar[n]+=3;
}
因ؓ(f)restar是访问分配的内存的唯一且初始的方式Q那么编译器可以上q对restar的操作进行优化:(x)
   restar[n]+=8;

而parq不是访问数lar的唯一方式Q因此ƈ不能q行下面的优化:(x)
   par[n]+=8;
因ؓ(f)在par[n]+=3前,ar[n]*=2q行了改变。用了关键字restricQ编译器可以放心地q行优化了。这个关键字据说来源于古老的FORTRAN。有兴趣的看?a >q个?/font>



dennis 2007-08-04 15:34 发表评论
]]>
如何讄一个基本的OpenLDAP Server(转蝲Q?/title><link>http://www.aygfsteel.com/killme2008/archive/2007/07/14/130281.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 14 Jul 2007 08:08:00 GMT</pubDate><guid>http://www.aygfsteel.com/killme2008/archive/2007/07/14/130281.html</guid><wfw:comment>http://www.aygfsteel.com/killme2008/comments/130281.html</wfw:comment><comments>http://www.aygfsteel.com/killme2008/archive/2007/07/14/130281.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/killme2008/comments/commentRss/130281.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/killme2008/services/trackbacks/130281.html</trackback:ping><description><![CDATA[<p>如何讄一个基本的OpenLDAP Server <br>本文:http://www.linuxforum.net 作?吴阿?Jephe wu (2001-09-04 15:00:01) </p> <p>      一. 目的  </p> <p>      本文旨在介绍如何安装OpenLDAPq且讄一个公司内部的集中化的邮g地址薄服务器供客 <br>      L(fng)查询?nbsp; <br>      基本上,OpenLDAPgq应用在其它许多斚wQ象集中化的用户帐号验证服务?但邮件地址 <br>      薄查询是最常用的?nbsp; </p> <p>      ? 安装  </p> <p>      ?a >www.openldap.org</a>下蝲最新的openldap软g包,按照~译和安装的步骤Q依ơ运行:(x) </p> <p><br>      #tar cvfz openldap-stable-20010524.tgz  <br>      #cd openldap-2.0.11  <br>      #./configure  <br>      #make depend  <br>      #make  <br>      #make test  <br>      #make install  </p> <p>      我的操作环境是redhat 6.1Q如果没有遇CQ何错误,最后默认安装LDAP后台E序slapd <br>      到目?usr/local/libexec;配置文g在目?usr/local/etc/openldap/ q且攑֐U?<br>      OpenLDAP工具 <br>      ldapadd,ldapdelete,ldapmodify,ldapmodrdn,ldappasswd,ldapsearch 在目?<br>      /usr/local/bin,q行时数据库?usr/local/var/openldap-ldbm ?nbsp; </p> <p><br>      ? 讄  </p> <p>      1) 更改配置文g/usr/local/etc/openldap/slapd.conf  <br>      在include /usr/local/etc/openldap/schema/core.schemaq行后面加上下面的行Q?<br>      包括所有的Ҏ(gu)?nbsp; </p> <p>      include /usr/local/etc/openldap/schema/corba.schema  <br>      include /usr/local/etc/openldap/schema/cosine.schema  <br>      include /usr/local/etc/openldap/schema/inetorgperson.schema  <br>      include /usr/local/etc/openldap/schema/java.schema  <br>      include /usr/local/etc/openldap/schema/krb5-kdc.schema  <br>      include /usr/local/etc/openldap/schema/misc.schema  <br>      include /usr/local/etc/openldap/schema/nadf.schema  <br>      include /usr/local/etc/openldap/schema/nis.schema  <br>      include /usr/local/etc/openldap/schema/openldap.schema  </p> <p>      2) 在文件slapd.conf?ldbm database definitions"部分更改相应?<br>      suffix,rootdn行如?nbsp; </p> <p>      database ldbm  <br>      suffix "o=yourdomain,c=us"  <br>      rootdn "cn=root,o=yourdomain,c=us"  <br>      rootpw secret  <br>      directory /usr/local/var/openldap-ldbm  </p> <p>      有各U格式你可以用,q里我用的是o=yourdomain,c=us 说明你的公司域名和所在的?<br>      家或地区  <br>      rootdn的格式安装后默认为cn=Manager,q里改ؓ(f)root完全是自q喜好,q样W合 <br>      Unix/Linux中rooth最高权限的传统?nbsp; </p> <p>      3) 现在可以启动slapd了,q行/usr/local/libexec/slapd ?nbsp; </p> <p>      可以考虑?usr/local/bin and /usr/local/libexec加到搜烦路径中,卛_?<br>      /etc/profile  <br>      中的PATH?  <br>      PATH="$PATH:/usr/X11R6/bin:/usr/local/bin:/usr/local/libexec"  <br>      q样下次d后只需键入 slapd ?nbsp; </p> <p>      4) 试ldap server是否正常工作?nbsp; <br>      q行下面的命令检查是否有相应的输出?nbsp; </p> <p>      #ldapsearch -x -b 'o=yourdomain,c=us' '(objectclass=*)'  </p> <p><br>      5) ~辑.ldif文本文gQ用ldapaddd记录q入LDAP数据库?nbsp; <br>      文g内容如下Q?nbsp; </p> <p>      dn: o=yourdomain,c=us  <br>      objectclass: dcobject  <br>      objectclass: organization  <br>      o: yourdomain  <br>      dc: yourdomain  </p> <p>      dn: cn=Jephe Wu,o=yourdomain,c=us  <br>      objectclass: inetorgperson  <br>      cn: Jephe Wu  <br>      sn: Wu  <br>      mail: <a href="mailto:jephe_wu@yourdomain.com">jephe_wu@yourdomain.com</a>  </p> <p><br>      ......more users......  </p> <p>      依次cLQ添加每个h的记录进入该文g中,注意对象cd inetorgperson 臛_必须?<br>      有cn和sn  <br>      ,q里我们用cn,sn,mail三项定义,q对我们的邮件地址薄功能来说已l够。你q可?<br>      定义?nbsp; <br>      mobile, homephone,pager......{等?nbsp; </p> <p>      然后用下面的命od上面?ldif文gq入LDAP数据?nbsp; </p> <p>      #ldapadd -x -D "cn=root,o=yourdomain,c=us" -w secret -f <br>      "yourldiffilename"  </p> <p>      注:(x)上面的文件的W一部分"dn: o=yourdomain,c=us"是必ȝQ否则不能添加数据?nbsp; <br>      用你的公司的域名替换上面?yourdomain"?nbsp; </p> <p>      6) 讄Outlook Express, 允许用LDAP服务器查询邮件地址?nbsp; </p> <p>      "工具/帐号/d--目录服务"Q填入你的服务器的IP地址或者主机全U域名,在下一个屏 <br>      q中选yes以允许用目录服务来查询地址Q最后在"目录服务"栏中选中刚才讄的项目击 <br>      “属?高",?搜烦?中填?nbsp; <br>      "o=yourdomain,c=us" ?nbsp; <br>      Netscapeh据上面的信息讄相应的选项?nbsp; </p> <p>      ? 常见使用问题  </p> <p>      1) 能启动slapd 没有问题Q但不能d数据库,q行ldapaddd时出?"ldap_bind: <br>      cannot contact LDAP Server" ?nbsp; <br>      {? 最可能的原因是?etc/hosts中没?27.0.0.1 localhost目?nbsp; </p> <p>      2) 注意查询序: 如果在Outlook Express的地址薄中有内容,则检查地址时地址薄优 <br>      先,如果在本地地址薄中找不到相应记录,然后再查询LDAP服务器?nbsp; </p> <p>      3) 用下面的命o信客户端与LDAP服务器有通讯,在服务器q行下面的命令,然后在OE?<br>      试查地址Q你会(x)得到查询LDAP数据库的q接q程的输出?nbsp; </p>       # tcpdump port 389  <br><img src ="http://www.aygfsteel.com/killme2008/aggbug/130281.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/killme2008/" target="_blank">dennis</a> 2007-07-14 16:08 <a href="http://www.aygfsteel.com/killme2008/archive/2007/07/14/130281.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>redhat9安装subversion手记http://www.aygfsteel.com/killme2008/archive/2007/07/06/128569.htmldennisdennisFri, 06 Jul 2007 05:47:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/07/06/128569.htmlhttp://www.aygfsteel.com/killme2008/comments/128569.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/07/06/128569.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/128569.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/128569.html1) Subversion 1.2.3
http://subversion.tigris.org/downloads/subversion-1.2.3.tar.gz

2)Berkeley DB 4.4.20
http://downloads.sleepycat.com/db-4.4.20.tar.gz

3)Apache 2.0.54
http://apache.justdn.org/httpd/httpd-2.0.54.tar.gz

二、以root用户登陆pȝ?br>
安装Apache
#tar -zxvf httpd-2.0.54.tar.gz
#cd httpd-2.0.54
#./configure --enable-dav --enable-so --enable-maintainer-mode
#make
#make install

安装Berkeley DB
#tar -zxvf db-4.4.20.NC.tar.gz
#cd db-4.4.20.NC/build_unix/
#../dist/configure --prefix=/usr/local/bdb
#make
#make install

安装Subversion
#tar -zxvf subversion-1.2.3.tar.gz
#cd subversion-1.2.3
#./configure --with-berkeley-db=/usr/local/bdb --with-apxs=/usr/local/apache2/bin/apxs
#make
#make install
/* 你可以用以下命o验subversion是否安装成功 */
#svnadmin --version

三、新Z用户lsvnQƈ建立一用户svnrootQ用于管理svn的运行和l护
groupadd svn
useradd -G svn -m "the svn mananger" svnroot
passwd svnroot  #讄svn密码

四、用svnrootdQ执行下列操?br> # mkdir /home/svnroot/repository

//创徏仓库test
svnadmin create /home/svnroot/repository/test

//导入目C库中
svn import /home/yourproject file:///home/svnroot/repository/test –m "initial import"
//改变权限Q仅限svnroot拥有诅R写、执行权?br> chmod 700 /home/svnroot/repository

五、root用户dQ设|Apache
//~辑httpd.conf
# vi /usr/local/apache2/conf/httpd.conf
   扑ֈ下面两行Q如果没有,则添加:(x)
   LoadModule dav_svn_module modules/mod_dav_svn.so
   LoadModule authz_svn_module modules/mod_authz_svn.so
   接着上面再添加下面这D配|:(x)
 <Location /svn/>
   DAV svn
   SVNParentPath 
/home/svnroot/repository/
   AuthzSVNAccessFile 
/home/svnroot/repository/authz.conf
   AuthType Basic
   AuthName 
"Subversion.svn"
   AuthUserFile 
/home/svnroot/repository/authfile
   Require valid
-user
   
</Location>

q段信息讄?svn/目录需要认证才能访问,用户信息攑֜authfileQ授权信息在authz.conf文g里?br>
六、权限管理,使用svnrootd
1Q增加用P通过下列命oW一ơ增加时建立authfile文gQ比如添加了一个用户dennis
htpasswd -c /home/svnroot/repository/authfile dennis
?x)提CZ输入密码Q以后再d׃?c选项?br>
2Q权限分?建立q编辑authz.conf
# vi /home/svnroot/repository/authz.conf
[groups]  #q个表示组讄
admin
=svnroot  #svnroot是adminl?br>[test:/]  #q表C,仓库test的根目录下的讉K权限
dennis
=rw #test仓库dennis用户hd写权?br>[test2:/] #假设有test2仓库,它的讉K权限
dennis
=r  #test2仓库dennis有读权限
[
/] #q个表示在所有仓库的根目录下
* = r     #q个表示Ҏ(gu)有的用户都具有读权限
@admin
=rw #adminl有d写权限,比如svnroot


讄完成后,
重启apache
/usr/local/apache2/bin/apachectl restart
启动svn服务
#svnserve -d

通过览器访问http://localhost/svn/test/Q输入用户名密码Q一切OKQ?br>
我只在我的windows机器上安装了subversion理我的文档Q这ơ在redhat9上的安装q算利Q参考了下列文章Q?br>?strong>Linux 上安?Subversion?/a>
《在Redhat9 Linux下安装,配置Subversion 1.3.1?/a>
 


dennis 2007-07-06 13:47 发表评论
]]>
q上了shell~程Q推荐好书一?/title><link>http://www.aygfsteel.com/killme2008/archive/2007/07/05/128347.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 05 Jul 2007 07:06:00 GMT</pubDate><guid>http://www.aygfsteel.com/killme2008/archive/2007/07/05/128347.html</guid><wfw:comment>http://www.aygfsteel.com/killme2008/comments/128347.html</wfw:comment><comments>http://www.aygfsteel.com/killme2008/archive/2007/07/05/128347.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/killme2008/comments/commentRss/128347.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/killme2008/services/trackbacks/128347.html</trackback:ping><description><![CDATA[    shell~程Q类似dos下的批处理文Ӟ也有很大不同Qshell更接q一门编E语a。最q迷上了q玩意,入门很容易,再深入就有点难了Q写了几个简单的script处理日常命oQ用着蛮爽Q大大提高了我l深入学?fn)linux的积极性,待复?fn)了C语言基础Q准备读诅R?a class="blue13" target="_blank">UNIX/LINUX~程实践教程</a>》。前天在emule下了《EveryDay Scripting With Ruby?q本书在amazon评h(hun)很高Q昨天一口气M6章,非常不错。这本书适合ruby初学者,有一定ruby使用l验的也能有不少收获Q书中介l了4个常用的ruby~写的工兯本,循序渐进、一步一步引你走入ruby的世界,有趣q实用;更可늚是,q本书从W?个Project开始就以TDD的方式开发,让你充分体验TDD和Rubyl合带来的快感,强烈推荐准备开始学ruby的看看这本书。读q本书主要是x深入地将ruby使用在我的日常工作中Q熟识部分飞快翻q,d也才250多页Q花不了一两天功夫。这本书的源码从|站上下不了Q封了来自中国大陆的IPQ我源码传上,有兴的看看?br><br><a href="http://www.aygfsteel.com/Files/killme2008/bmsft-code.zip">《EveryDay Scripting With Ruby》书中源?/a><br><br> <img src ="http://www.aygfsteel.com/killme2008/aggbug/128347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/killme2008/" target="_blank">dennis</a> 2007-07-05 15:06 <a href="http://www.aygfsteel.com/killme2008/archive/2007/07/05/128347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vi常用命ohttp://www.aygfsteel.com/killme2008/archive/2007/07/03/127735.htmldennisdennisTue, 03 Jul 2007 01:17:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/07/03/127735.htmlhttp://www.aygfsteel.com/killme2008/comments/127735.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/07/03/127735.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/127735.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/127735.html1.讄昄行号  :set nu
  取消昄行号  :set nonu
2.光标Ud到n?nG
  光标Ud到最后一?G
3.光标Ud到本行第n个字W?nI格
  光标Ud到本行最后一个字W?$
4.向光标之后搜索字W串 /word
  向光标之前搜索字W串 ?word
5.从第n1行到Wn2行搜索word1字符Ԍq替换ؓ(f)word2   :n1,n2s/word1/word2/g
  逐个替换   :n1,n2s/word1/word2/gc
  从第一行到最后一行进行替换应该是              :1,$s/word1/word2/g
6.向前页 ctr+f
  向后页 ctr+b
7.恢复修改操作 u
8.复制本行 yy
  本行往下n行进行复?nyy
9._脓(chung)在光标以下的?p
  _脓(chung)在光标以上的?P
10.向后删除一个字W?x
   向前删除一个字W?X
   向后删除n个字W?nx
11.保存   :w
   退?nbsp;  :q
   强制退Z保存 :q!
   强制保存   :w!
   保存q?:wq
   另存?nbsp;    :w otherfilename
  




dennis 2007-07-03 09:17 发表评论
]]>
Erlang分布式在linux和windows上的注意事项http://www.aygfsteel.com/killme2008/archive/2007/06/29/127099.htmldennisdennisFri, 29 Jun 2007 08:33:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/06/29/127099.htmlhttp://www.aygfsteel.com/killme2008/comments/127099.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/06/29/127099.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/127099.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/127099.html
1.首先,分布式Erlang的实现提供了自有的安全机制来预防未经授权的Erlangpȝ讉K。Erlangpȝ与别的机器进行交互时必须有同L(fng)magic cookie,保存在一个称?erlang.cookie的文件中Qؓ(f)了在两台不同机器间测试,需要编辑一?erlang.cookie,内容随便Q比如:(x)
just_test

然后这份文件拷贝到windows环境变量HOMEPATH所在的目录 Q比如我的是C:\Documents and Settings\AdminQ而linux拯到环境变?HOME指向的目录,比如我这里是/root。特别注意一点,linux?erlang.cookie文g需要设|权限ؓ(f)-r--------Q也是400Q仅所有者可读:(x)
chmod 400 .erlang.cookie

2.因ؓ(f)Erlang中的node名称是name@hostQhost是计机名,因此在两台机器上都需要将计算机名和ip加进hosts文gQ这个文件在linux下是?etc/hostsQ你可以用vi~辑如下Q?br>
127.0.0.1  localhost localhost
x.x.x.x    zane      zane
   #windows机器的ip和计机?/span>
Qhosts在windowspȝ的C:\WINDOWS\system32\drivers\etc目录下,~辑Q?br>
127.0.0.1       localhost
x.x.x.x   dennis 
#linux机器的名U和ip

3.W三步,要启动节点,通过命oerl -sname 或者erl -nameQ在此之前需要启动epmdq程Q它负责映射W号名到机器地址
在两个机器都执行Q?br>epmd -daemon

4.x配置完成Q可以测试下Erlang分布式编E在不同的机器和pȝ之间了(比如?a href="http://www.aygfsteel.com/killme2008/archive/2007/06/15/124547.html">Erlang入门(?--分布式编E?/a>》中的ping pong例子Q,very cool!



dennis 2007-06-29 16:33 发表评论
]]>
redhat9安装jdk5、ruby和Erlang备忘http://www.aygfsteel.com/killme2008/archive/2007/06/28/126886.htmldennisdennisThu, 28 Jun 2007 10:08:00 GMThttp://www.aygfsteel.com/killme2008/archive/2007/06/28/126886.htmlhttp://www.aygfsteel.com/killme2008/comments/126886.htmlhttp://www.aygfsteel.com/killme2008/archive/2007/06/28/126886.html#Feedback0http://www.aygfsteel.com/killme2008/comments/commentRss/126886.htmlhttp://www.aygfsteel.com/killme2008/services/trackbacks/126886.html
一。安装jdk5
1.到sun的网站上下蝲jdk5与netbean5.5的捆l版本,注意要linuxq_?br>
2.比如下蝲?root/目录下,执行
chmod 755 jdk-1_5_0_12-nb-5_5_1-linux-ml.bin
然后执行Q?br>./jdk-1_5_0_12-nb-5_5_1-linux-ml.bin
׃(x)自动启动安装向导Q一路选择定下去O(jin)K了?br>
3.讄环境变量Q这时其实没有设|就可以启动netbean了,不过Z在终端执行,q是要设|下环境变量Q用vi~辑/etc/profile配置文gQ在最后面加上Q?br>
JAVA_HOME=/opt/jdk1.5.0_12
PATH
=/opt/jdk1.5.0_12/bin:$PATH
CLASSPATH
=/opt/jdk1.5.0_12/lib/dt.jar:/opt/jdk1.5.0_12/lib/tools.jar
export JAVA_HOME PATH CLASSPATH
保存退出,reboot下就O(jin)K

二。安装ruby
1.到ruby-lang.org下蝲ruby-1.8.6.tar.gz
2.解压~ƈq入解压后的目录Q?br>tar xzvf ruby-1.8.6.tar.gz
cd ruby-1.8.6

3.默认是安?usr/local目录下,可以通过下面的命令设|安装到/usr/local/ruby目录下:(x)
/.configure -prefix=/usr/local/ruby

4.执行命oQmake && make install

5.再次~辑vi /etc/profileQ修Ҏ(gu)们在上面提到的PATHQ把ruby的bin加进去:(x)
PATH=/usr/local/ruby/bin:/opt/jdk1.5.0_12/bin:$PATH

6.试下是否正安装,
ruby -version
ruby -e "puts 'hello'"

三、Erlang的安?br>
1.到Erlang.org下蝲最新版本的linuxq_下的ErlangQ源代码版本Q需要自q译)Q比如otp_src_R11B-5.tar.gz

2.解压~,q进入解压后的目录:(x)
tar zxvf otp_src_R11B-5.tar.gz
cd otp_src_R11B-5

3.build Erlang需要下列工P认你的linux版本有安装:(x)
 GNU make

 GNU C compiler

 Perl 5

 OpenSSL

 Sun Java jdk-1.2.2

 X Windows

 sed  solarisq_需?br>
 Flex 可?br>
4.安装q程Q顺序执行下列命令,包括OTP在内都将被安?br>
1)export LANG=#如果是C ShellQ执行setenv LANG C,linux一般是Bourne shell



2)./configure

3)make

4)make install

5.认安装正确Q新开一个终端,执行erlq入Erlang shell

最后启动下sshQ允?dng)R火墙通过ssh执行下面的命令,在windows上搞个putty
iptables -A INPUT -p tcp --sport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT






dennis 2007-06-28 18:08 发表评论
]]>
վ֩ģ壺 | | | | | | İ| | ٳ| ¡| | ˮ| ɽ| | | ɳ| ٹ| ʢ| | ײ| | ũ| | ɽ| | | | | | | | | | | ǹ| | | ʹ| ˮ| | |