Posted by rainx on October 8, 2006
呵呵,今天要写一个性能测试的程序,由于之前用过boost的thread,所以就采用了boost的thread库
程序大概是根据指定的参数来生成多个线程来进行一个操作…本来满简单的..但是之前时候不知道boost有进程组的支持…所以只能自己动态的建立一大堆 thread ..放到一个容器中..然后在遍历join下,然后再在结束前delete他们,很麻烦..不过最后还是实现了。不过就在完成之后,同事晓哲给我看了一下他的程序..用到了boost的thread_group ,这才发现原来boost也有进程组的支持阿…晕….刚才试着写了一个简单的程序…呵呵,根据指定参数生成指定个数的子程序… 很简单阿..再也不用遍历一遍每一个join一下了..join_all就搞定了..
下面是代码,呵呵,很简单吧
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace boost;
using namespace std;
void runChild(const int n)
{
cout << "我是第" << n << "个子线程" << endl;
sleep(1);
cout << "进程" << n << "退出" << endl;
}
int main(int argc, char** argv)
{
int num;
thread_group threads;
if (argc < 2)
{
cout << "请提供一个要生成线程数的参数" << endl;
exit(-1);
}
num = atoi(argv[1]);
cout << "我是主程序,我准备产生" << num << "个子线程" << endl;
for(int i = 0; i < num; i++)
{
threads.create_thread(bind(&runChild, i));
}
cout << "我是主程序,我在等子线程运行结束" << endl;
threads.join_all();
return 0;
}
编译&测试(我在我的ubuntu下测试的)
> g++ threadgroup.cc -lboost_thread
> ./a.out 3
如果在freebsd4下编译的话,如果使用pthread作为线程实现的话,需要明确指出pthread使用线程库,而且默认的template深度好像不能满足boost的需求..需要在编译时加上:
-ftemplate-depth-20 -boost
Posted by rainx on September 25, 2006
Unihan是unicode.org下的一个子项目,它本身是一套非常完备的基于unicode标准的CJK文字字符集的参考手册,里面包含了非常丰富的汉字元信息,如发音,释意,编码,笔划等信息.. ,其中unicode项目将这些信息存储在一个非常大的文本数据库中(在他的网站上可以下载到)… ,格式为
U+[CodePoint] [tab] key [tab] value
当然,还有很多行为注释(注释是以#开头的)
这样虽然简单明了,但是不如放到关系型数据库中检索方面,于是做了简单的perl脚本来解析导入数据库…
数据库sqlite
sqlite> CREATE TABLE hanzi( zi char(3) , k char(100), v text, PRIMARY KEY(zi,k));
注意这理我有一个失误,其实在开始的时候没有必要建立主键,可以在导入之后统一建立,因为数据库的索引的确很影响insert的速度.
perl脚本
#!/usr/bin/perl -w
use strict;
use DBI;
use constant UNIHAN_DB => "unihan.db";
use constant UNIHAN_FILE => "Unihan.txt";
# db handler
my $dbh = DBI->connect("dbi:SQLite2:dbname=" . UNIHAN_DB . "", "") || die("DB open err");
# open file
open (UNIFILE, UNIHAN_FILE) || die("FILE open err\n");;
# prepare
my $sth = $dbh->prepare(‘insert into hanzi (zi, k, v) values ( ?, ?, ?)’);
while(my $line = <unifile>)
{
next if ($line =~ /^#.*/);
chomp($line);
my ($zi , $k, $v) = split(/\t/, $line);
my $zi_utf8 = chr(hex(substr($zi, 2)));
$sth->execute($zi_utf8, $k , $v) || print "sql excute err";
}
$sth->finish();
#close file and db
close(UNIFILE);
$dbh->disconnect();
ok…就酱紫了(哎,对perl还是很不熟啊..还好部门现在有很多perl的高手)
Posted by rainx on September 17, 2006

过些日子要给同事介绍PHPUnit,so,今天晚上忙到现在(快凌晨4点了)写了一篇关于PHPUnit的Presentation , 算是一个初稿吧,是用Openoffice 的 presentation写的,转换成ppt格式,不知道在windows下看效果怎么样
想看看的可以到这里下载:
http://rainx.cn/documents/phpunit/PHPUnit.ppt
Posted by rainx on September 7, 2006
24岁之后,在脆弱的人哭的机会都会很少…. 所以,每一次都不能忘记。
不知道为什么,突然觉得…. 很多东西需要珍惜…
Posted by rainx on September 3, 2006
对Bt感兴趣好一阵子了, 不过一直都没有好好分析一下bt所应用的协议, 今天 上了一下bt的官方网站, 研究了一下 bt 的协议 (http://www.bittorrent.org/protocol.html) , 费尽千辛万苦才读了大约2/3的内容,发现英文的读起来不爽(虽然比较简单),所以搜了搜中文的网站,发现早就有人翻译过这篇协议说明了, 在这里:
http://callof.net/Site/pView.Asp?id=614
还有比较好的一篇就是姚同学的 Ctorrent 程序源码分析
http://yaoxuchen.googlepages.com/ctorrent
虽然已经有了精彩的文章,我还是把我分析时所画的图扔上来吧,呵呵
A 我自己分析的Bt客户端下载的流程

B 分析tracker信息时用ethereal的截图

Posted by rainx on August 22, 2006
很简单实用的东东, 类似unix下shell中的交互式环境,可以在这里面交互的执行,调试js程序..
特征如下 :
* You can enter statements and expressions at the same prompt.
* The result of each non-void statement or expression is shown.
* User-defined variables.
o b = document.body
* User-defined functions.
o function f() { return 5; }
* JavaScript error messages are shown in red.
* Previous statements and expressions are available through Up and Down arrow keys.
* Tab completion.
* Multiline input (Shift+Enter to insert a line break).
* If the shell is opened using a bookmarklet, JavaScript typed into the shell runs in the context of the original window.
* Works well in Firefox, mostly works in Opera 8 and in IE 6 for Windows.
其他的不多说的… 很实用…. 强烈推荐, 他的官方网页上有更加详细的介绍
http://www.squarefree.com/shell/
Posted by rainx on August 17, 2006
呵呵, 很久没有更新blog了的说
因为我突然想到之前我做得一个项目时积累的一些心得,呵呵,怕自己忘记了,所以写在Blog里好了, N个月前我接触了一个移植美国的一个C++系统的项目,项目的目标是要将所有基于不同数据源的数据统一为单独的接口,这样用户访问底层数据源信息就不用同时调用N多不同的接口进行访问,而且ACL等信息管理也可以统一到一组前端服务器上来控制,这样更加便于管理。
项目涉及到的数据源有各种各样不同的类型,有数据库,文件系统,还有各式各样自己开发的数据管理系统。所以美国方面就采用了一种类似设计模式中的Adaptor模式的技术来处理与后端数据源交互的部分。其中比较灵活的是针对每个数据源的Adaptor都放在一个单独的.so文件中…这样如果有新的数据源加入的话,并且添加新的adaptor之后可以由一个配置文件来管理和维护,这样大大的提高了程序的通用性,例如这次中国移植这个程序的时候,虽然中国和美国的数据源不同,但是我们移植的时候并没有修改主体程序的部分,只是写了新的Adaptor,并且修改了配置文件就可以了。
N个月之前的某天我按照他的思想写了一些类似的代码,就是可以根据指定的路径来动态载入(dlopen) 需要的类并且实例话之(当然了,程序经过简单的修改就可以变成可配置的),我这里简化的很多,当然了,由于主体程序是可以在开发adaptor之前开发的,所以adaptor需要实现相同的接口才行(在这里,构造函数和主要处理函数都是虚函数),每个Adaptor需要遵循。对了,不要将它和设计模式里的Adaptor模式挂钩,虽然名字很像,但是这个例子不是Adaptor模式的例子(更像是Factory,呵呵)
[代码下载]
这个代码在握自己的ubuntu linux 的机器上编译通过, 下载后
tar xvf adaptor.tar
cd step1 ; make
即可,但是需要修改test.c 里面的ADDSOPATH ,和DECSOPATH 到你的path哦,另外程序为了解决map中动态添加的adaptor对象的释放问题,是用了boost的智能指针shared_ptr,如果编译的话也要安装boost的库哦。
不太多说明了,附上部分代码:
loadAdaptor函数
typedef boost
::shared_ptr<adaptor
> adaptor_p
;
int loadAdaptor(map<string, adaptor_p>& adaptorMap, const char* path)
{
void* handle = NULL;
create_t* create_adaptor;
handle = dlopen(path, RTLD_LAZY);
if(handle == NULL)
{
cerr << "load err" << endl;
}
create_adaptor = (create_t*) dlsym(handle, "create");
adaptor_p adaptor(create_adaptor());
adaptorMap[path] = adaptor;
return 0;
}
Adaptor基类
adaptor.h
#ifndef __ADAPTOR_H__
#define __ADAPTOR_H__
#include <string>
using namespace std;
/**
* The base class/interface of all adapotrs
*/
class Adaptor
{
protected :
string myName;
public :
Adaptor(const char* adaptorName);
virtual ~Adaptor(){};
virtual int process(int a,int b) = 0;
};
typedef Adaptor* create_t(void);
#endif
adaptor.cc
#include "Adaptor.h"
#include <string>
Adaptor::Adaptor(const char* adaptorName)
{
myName = adaptorName;
}
其中的一个具体子类,加法的例子,还有一个减法的,下载的源码里有。
#include "AddAdaptor.h"
#include "Adaptor.h"
AddAdaptor::AddAdaptor(const char* adaptorName) :Adaptor(adaptorName)
{
}
int AddAdaptor::process(int a, int b)
{
int c = a + b;
return (c);
}
extern "C" Adaptor* create(void)
{
return new AddAdaptor("add");
}
Posted by rainx on July 24, 2006

首先,感谢一直在使用solor的人,感谢喜欢和不喜欢solor的人,感谢一切为solor作出贡献和帮助的人,谢谢你们…
由于服务器到期加上我本人最近工作比较忙,可能没有太多的时间来照顾solor,所以……. solor将暂时关闭.. ,当然solor会很快回来,请相信RainX。
solor的成立到现在已经有7个多月了,7个月前,记得是一个周末,RainX花了不到两天的时间完成了solor的主要核心代码,并建立的网页(这里要感谢提供服务器的合伙人
)。solor成立之处的主要目标是简化人们从互联网上获取视频的过程,并帮助人们分享视频。最然页面比较简陋,但是RainX却非常喜欢它..当然,solor也改变了RainX的生活:
记得最开始的时候,也就是刚刚写好solor,那个时候没有人知道,所以RainX就跑到当时非常火的百度贴吧上贴了几条solor的信息,并且写了使用教程
http://post.baidu.com/f?kz=72086182
然后,马上登录到服务器上 tail -f access.log 文件来监控访问日志….. 看着日志一行一行的增长…真的是很有成就感呢.
在然后… 有了solor的豆瓣小组
http://www.douban.com/group/11925/
然后接到投诉… 修复bug…..
然后….
PV一点点的增加… 然后百度可以搜到solor…. 然后不知不觉有认识和不认识的朋友将它放到自己的blog上宣传 ~~~
然后…
……….
真的谢谢大家了,Solor会回来的
Posted by rainx on July 9, 2006
拥有英俊的外表,飘逸长发的戈麦斯终于在最后一场比赛中证明了自己。在斯科拉里手下的葡萄牙队里,他,缺少的只是机会~~~~
另外,还是说说菲戈,与德国比赛其实本来根本就没有什么太大的价值,3-4名的比赛向来被认为是鸡肋,本来没想到菲戈会出场的,没想到最后还是上了15分钟,呵呵,也许最后时刻的上场只是为了和卡恩告别吧.. 两个伟大的球星在这场比赛之后都永远的退出了国家队。
Posted by rainx on July 6, 2006
这结世界杯有太多太多的历史重演了,葡萄牙队不是败给法国,而是败给了宿命…. 同样是半决赛,同一个人,同样是点球……
哎,真是想不通,拥有这么强大的中场的球队怎么会没有一个相衬的前锋… 尢西比奥何时也来一个灵魂附体 …
16年,足以让一个初生的婴儿变成翩翩少年, 在16年之前菲戈见证了黄金一代的辉煌的起点,现在,作为黄金一代的最后代表,菲戈载着黄金一代的梦想战斗到了最后,这场比赛之后,宣告了葡萄牙华丽的黄金一代的谢幕…. 波尔图王朝的到来…德科们, 继续战斗吧!!