博文

目前显示的是 十二月, 2007的博文

教训:装完gcc42后记得要重装libtool

今天很郁闷,发现,明明是用g++42编译的ImageMagick,但是其依赖的so还是libstdc++.so.5,应该是libstdc++.so.6才对。反复多次编译,都未解决。查make的输出,也都一切正确。
后来突然想到,可能是libtool 的问题,而且这家伙在每次调用libtool的时候都加了--silent参数隐藏了真正的命令执行过程。 重装libtool后,一切果然恢复。
回想下,这次第二次遇见这样的问题。上次没有记录下来。唉……

最近在看的书

最近在看的书,
《哲学概论》&& 《哲学要义》,每本看了3-4章就扔下了
《健康心理学》 看目录的时候觉得有趣,越往里看越受不了,我不关心那些试验数据以及分析,给我点科普性的结论就行了。
《The Java Programming Language》,作者之一是Java之父。我耐着性子看完了100页,但是这本书有800多页,光附录就有150页,所以,2个月内,是没指望看完了。
最近3个月读了2本小说,一本法国小说〈救救我〉,一本中国小说〈阿难〉,都是看的索然乏味的那种。
对了,上个月逛万圣和单向街的时候,发现它们都在力推一本书,〈协和医事〉,被列在榜首推荐。然后我就买了,结果……结果…… 也许是内容太积极向上了,尽是溢美之词,所以我翻了3、4章就困了,扔墙角去了。谁要有兴趣来我家拿哈。
顺便向广大青年,以及晚上睡不着爱失眠的人,推荐一本书:“责任的落寞:新民主时期的无痛伦理观”。这本书90s出的,可以用来吸纳下现代思想。

Freebsd中fileno和fileno_unlocked的区别

从一个open返回的fd创建一个FILE*,所用的函数是fdopen。而反过来,就是用fileno。
由于FILE*所指向的是一个复杂的数据数据结构,一个进程内的所有线程共享这些数据,所以在使用fileno获取FILE*内容的时候,必须先使用flockfile或pthread_mutex_lock这样的函数加锁,这一点是由libc中的fileno函数本身完成的,调用fileno函数的用户并不用关心这些。而fileno_unlocked和fileno的实现上的区别就是,前者没有加锁/释放锁。
如果
1、你的程序是单线程
2、或者,尽管是多线程,但是可以保证同一时间内只有一个线程会对这个FILE*调用fileno函数
那么就可以采用fileno_unlocked代替fileno
类似的还有clearerr_unlocked、feof_unlocked、ferror_unlocked。

伟大的java就这么否决了swap函数

在C++中,要交换一对变量,就这么简单
int a(10),int b(20);
std::swap(a,b);
不管a和b是什么类型,不管是基本类型、还是复杂类型,还是指针,都这么简单。
而java呢?可以写一篇长达数页的paper去论证,任谁也写不出这样的函数。
java的原则是,你可以把一段重复的代码写很多遍,只要:
1、这段代码很短
2、你确保你每次都不会写错
p.s. php程序员更有“天赋”:
list($a,$b) = array($b,$a);

在一个类的静态变量被完全初始化完前,调用其静态成员函数

java中,如果两个类的static initialization block相互调用怎么办? 一个类的static initialization block应该在一个类初次被使用时被调用。假如我有一个class A,它有一个static initialization block和一个名叫func的static function。还有一个叫做B的class,与A有同样的结构。 但是,特殊之处在于,如果A的static initialziation block会调用B.func这个静态函数,此时,因为发现class B的静态成员还没有初始化过,那么就会调用B的static initialization block,再如果此时B的这个block也调用A.func,那么此时该怎么办? 它会先执行A的static initialization block,执行到一半的时候再去执行B的static initialization block,此时,在A的所有变量尚未初始化完之前,进入A.func。OMG!

绕过防火墙:X11转发

我经常要连接远端的服务器,而由于种种原因,不仅防火墙加了很多限制,sshd的X11 forwarding和tcp forwarding也都被关闭了。但是没关系,自己装个tcp转发器就好了(这一点在sshd的文档中就有注明)。 下面,嘿嘿,看我是怎么把本机的6000端口转发到服务器上去的。
首先,下载个叫做netcallback的软件。http://netcallback.sourceforge.net/release/netcallback-1.3.1.zip
http://netcallback.sourceforge.net/release/netcallback-1.3.1.tar.gz然后,在本机运行xserver,那么它就会在tcp 6000端口执行监听。 最后,就是最重要的,我们要把这个端口利用netcallback转发出去。
1、在远程服务器上,运行
java -jar netcallback.jar -public -servicePort 63121 -tcpPort 6000
那么,netcallback就会在63121 和6000端口执行监听。其中63121 是netcallback和netcallback之间执行通讯的,传输一些控制信息。而6000是我们要转发的端口,用于传输x协议的数据信息。 2、在本机(运行X的机器)上运行
java -jar netcallback.jar -private -service xxx.xxx.xxx.xxx 63121 -tcp 127.0.0.1 6000
其中xxx.xxx.xxx.xxx是服务器的ip,63121是netcallback在xxx.xxx.xxx.xxx执行监听的端口。后面是要被转发出去的internet地址。 之后,所有发往xxx.xxx.xxx.xxx的6000端口的tcp请求以及数据,都会被转发到正在运行x的那台机器的6000端口。下面要做的就是把DISPLAY环境变量设置成127.0.0.1:0.0,就ok了!

《Java Programming Language》到了

《Java Programming Language》到了,第四版,Java之父的大作,很厚的一本。
嗯,从今天起,好好学java吧。 今天装eclipse的时候遇到了如下错误: Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine. 环境:Freebsd 6.2,diablo-jdk-1.5.0.07.01_8,找文档,改了下java的参数,一切ok。 setenv _JAVA_OPTIONS '-Xmx128m'

freebsd的sun rpc烂透了

亲爱的,稍微改进下你的程序吧,这不费多大事儿。
我在一个多线程的corba程序的多个worker线程中调用了sun rpc的clnt_create函数。然后我的程序偶尔会core dump.查了下,backtrace如下:
#0 0x84c7f82a in fclose (fp=0x0) at /usr/src/lib/libc/stdio/fclose.c:56
#1 0x84c4b0a2 in endnetconfig (handlep=0x86e0420) at /usr/src/lib/libc/rpc/getnetconfig.c:394
#2 0x84c40cc5 in __rpc_endconf (vhandle=0x86e0410) at /usr/src/lib/libc/rpc/rpc_generic.c:441
#3 0x84c327eb in clnt_create_timed (hostname=0x80977d8 "127.0.0.1", prog=931729681, vers=1,
netclass=0x80977d4 "tcp", tp=0x0) at /usr/src/lib/libc/rpc/clnt_generic.c:271
#4 0x84c3264d in clnt_create (hostname=0x80977d8 "127.0.0.1", prog=931729681, vers=1,
nettype=0x80977d4 "tcp") at /usr/src/lib/libc/rpc/clnt_generic.c:186
... 后面的我略了。
然后我打开netnetconfig.c看了下
endnetconfig中调用了fclose函数关闭一个叫做nc_file的file handle。而这个file handle是一个全局静态变量。
static FILE *nc_file;
然而在使用这个变量的时候,完全没有加锁。
如ni.ref++; if ((nc_file != NULL) || (nc_file = fopen(NETCONFIG, "r")) != NULL) { nc_vars->valid …

伟大的Douglas C. Schmidt居然是学社会学的

Douglas C. Schmidt是ACE的主要作者,我今天看了下他的resume,发现他居然本来是学社会学的。OMG~~Ph.D. Computer Science, summer 1994, University of California, Irvine
Dissertation: An Object-Oriented Framework for Experimenting with Alternative Process Architectures for Parallelizing Communication Subsystems.
Co-advisors: Dr. Tatsuya Suda and Dr. Richard W. Selby.M.S. Computer Science, summer 1990, University of California, Irvine, specializing in software engineeringM.A. Sociology, summer 1986, College of William and Mary, Williamsburg, Virginia
Thesis: ``A Statistical Analysis of University Resource Allocation Policies.''
Advisor: Dr. Michael A. FaiaB.A. Sociology, summer 1984, College of William and Mary, Williamsburg, Virginia
p.s.找到一本感兴趣的书,pattern-oriented software architecture vol 4: a pattern language for distributed computing.可惜国内还没有的卖,我刚下了电子版。

ACE_Svc_Handler的并发性问题

在ACE基于Reactor模式的 Acceptor-Connector 框架中:
当一个新的连接请求到达server时,会触发ACE_Acceptor的handle_input方法。
ACE_Acceptor的handle_input做三件事情:
1、调用make_svc_handle()创建一个新的 service handle。此时会调用该ACE_Svc_Handler的构造函数
2、调用accept_svc_handle(),执行accept
3、调用activate_svc_handle(),调用service handle的open方法。
在accept的时候,系统的accept函数会为每个新连接创建一个socket,然后ACE的模式是一个socket(ACE_HANDLE)对应一个ACE_Svc_Handler。在执行完accept方法后,该ACE_Svc_Handler就被Reactor关联到一个socket(ACE_HANDLE)上。当有新数据到达时,Reactor就会触发这个ACE_Svc_Handler的handle_input方法。
理论来讲一个ACE_Svc_Handler对应一个网络连接,发生并发冲突的情况很小。那么在哪些步骤可能发生并发呢?
1、首先,ACE_Svc_Handler的handle_input/handle_output/handle_close可能在open执行结束之前被调用。ACE在此模式中使用open来初始化一个对象而不是构造函数,是考虑构造函数难以处理创建中发生的各种错误(ACE不喜欢用C++ exception),那么给问题的处理带来很多麻烦。于是就用一个open函数来处理所有的初始化工作。但是,如果handle_input在open执行结束之前被调用,情况是比较可怕的。
2、ACE_Svc_Handler的析构函数可能在open执行结束之前被调用。例如handle_input返回负值的时候就会引发handle_close,而handle_close会调用delete this;删除自己,此时就会调用该对象的析构函数。而此时open正在对一些变量进行初始化,so....
那么,如何处理这些问题呢?对于每个网络连接,在每次数据接收之间经常是有一些状态需要保存的。嗯,尽量多用函数内的局部变量,少定义成员变量,多加锁。唉……