Boost的线程组thread_group

呵呵,今天要写一个性能测试的程序,由于之前用过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

制作Unihan数据库..

Unihanunicode.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的高手)

PHPUnit2的介绍

过些日子要给同事介绍PHPUnit,so,今天晚上忙到现在(快凌晨4点了)写了一篇关于PHPUnit的Presentation , 算是一个初稿吧,是用Openoffice 的 presentation写的,转换成ppt格式,不知道在windows下看效果怎么样

想看看的可以到这里下载:

http://rainx.cn/documents/phpunit/PHPUnit.ppt

记住,珍惜

24岁之后,在脆弱的人哭的机会都会很少…. 所以,每一次都不能忘记。

不知道为什么,突然觉得…. 很多东西需要珍惜…

关于Bt(Bit torrent) 协议

对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客户端下载的流程

BtClient

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

Bt-ethereal

Js shell , 方便的JS调试工具

很简单实用的东东, 类似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/

在linux下开发可动态扩展的C++程序

呵呵, 很久没有更新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");
}

Solor–暂时的离开

solor

首先,感谢一直在使用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会回来的

追风的少年-戈麦斯

拥有英俊的外表,飘逸长发的戈麦斯终于在最后一场比赛中证明了自己。在斯科拉里手下的葡萄牙队里,他,缺少的只是机会~~~~

另外,还是说说菲戈,与德国比赛其实本来根本就没有什么太大的价值,3-4名的比赛向来被认为是鸡肋,本来没想到菲戈会出场的,没想到最后还是上了15分钟,呵呵,也许最后时刻的上场只是为了和卡恩告别吧.. 两个伟大的球星在这场比赛之后都永远的退出了国家队。

宿命么?

这结世界杯有太多太多的历史重演了,葡萄牙队不是败给法国,而是败给了宿命…. 同样是半决赛,同一个人,同样是点球……

哎,真是想不通,拥有这么强大的中场的球队怎么会没有一个相衬的前锋… 尢西比奥何时也来一个灵魂附体 …

16年,足以让一个初生的婴儿变成翩翩少年, 在16年之前菲戈见证了黄金一代的辉煌的起点,现在,作为黄金一代的最后代表,菲戈载着黄金一代的梦想战斗到了最后,这场比赛之后,宣告了葡萄牙华丽的黄金一代的谢幕…. 波尔图王朝的到来…德科们, 继续战斗吧!!