cygwin 中 dll 路径

阅读更多关于《cygwin 中 dll 路径》

cygwin 中 dll 路径不是用 LD_LIBRARY_PATH 指定,而是 PATH,坑爹!
更坑爹的是, cygwin 中的 ldd 如果找不到某个 dll,竟然不报错,直接不显示那个 dll 文件!cygcheck 找不到依赖的 dll 时倒是会报错。

避免应用程序抢夺焦点窗口

阅读更多关于《避免应用程序抢夺焦点窗口》

最近老碰到当前窗口被抢焦点,却不知道是哪个程序抢了焦点,找到了这一篇文章: 继续阅读

How do I disable video thumbnails in Windows 7?

阅读更多关于《How do I disable video thumbnails in Windows 7?》

How do I disable video thumbnails in Windows 7!

禁用 视频 缩略图 windows 7 继续阅读

my PipelineProcessor

阅读更多关于《my PipelineProcessor》

刚看到,intel tbb::pipeline 实现的功能,和我以前实现的一个pipeline : febird::thread::PipelineProcessor
,介绍:

1. 多线程的 pipeline 设计模式

2. 多线程 Pipeline 的改进

 

几乎就是同一个东西:多线程流水线执行,按次序,stage划分……

可惜啊,它只在我的几个程序中用过,现在有了tbb,它还没来得及壮大就得夭折了。

 

聊以自慰:

    1. 英雄所见略同

    2. 这个轮子很有价值

    3. 发明轮子之前,先多看看

    4. 多看看,碰到问题就免得发明轮子

简单的代码生成器创建领域语言

阅读更多关于《简单的代码生成器创建领域语言》

有一类问题,代码模板相同,但有少部分地方不同,一般可以写一个复杂的程序,使用不同的选项,完成不同的任务。或者,把公共的部分抽象成一个代码库,然后在不同程序中引用。但是,如果公共的部分很少,并且比较“专用”,或者因为其它原因,比较难以部署。怎么办?

实际上,有另一种完全不同的编程模式来实现:代码生成器。unix世界中最知名的代码生成器莫过于lex和yacc了。但是,不比每个代码生成器都那么复杂,比如这个代码生成器就非常简单,它只是简单地转换行记录:

 

可以象awk一样写程序:

 

我当初写这个生成器的原因是发现非常简单的 awk 程序也比 C 慢 40 倍,以为这是本质上的性能差距,后来才发现不是

 

对这个简单的程序,使用awk更方便更安全,也不比C慢,但是一旦碰到其它类似问题而 awk 解决不了,这种模式就可以派上用场了。

管道的境界

阅读更多关于《管道的境界》

一直在想:如何在 Hadoop.MapReduce 中,插入一个 C 写的 HashFunction,既要高效,又要接口简洁。通过命令行实现调用显然是不行的。刚刚终于想出了:使用管道!

一个非常简单的程序,从stdin读入,写到stdout。多简单!至于效率,管道嘛,本质上就是异步的,自然是buffered&asynchronous 模式。

 

hash 程序

 

 

框架可以一边不断往管道写key,一边从中读取结果,这两个工作完全可以是异步的。对hash程序来说,如果stdin/stdout是全缓冲的,就几乎没有io的开销,因为几百几千次 fgets/printf 才会导致一次系统调用。

对frame程序也是一样的。

 

在 hadoop.streaming 中,hash 函数目前还必须由 java 类指定,如果使用这种方式,那就更 unix 了。

 

asio/ACE/apr/libevent

阅读更多关于《asio/ACE/apr/libevent》

整体感觉:ACE太庞大,asio 太赶时髦。

ACE太过庞大,使得你即便是只使用它的一小部分,也不得不引用它的全部。而且框架一大堆,模式一个加一个,很多编程习惯也要改变。学习曲线太陡,也难以将它作为一个模块集成自己的应用。

asio呢,有个牛大大说它是现时代的ACE,我觉得比较中肯。用bind做回调也并不比虚函数好,看上去灵活了,代价却更高了。我说的不光是运行时的内存和时间代价,更重要的编译时间难以忍受。

apr大约只是一个平台无关的api封装,相对来说比较轻量级。

libevent就更轻量级了,轻量级到无法把它当成一个平台无关的socket,还要写很多平台相关的代码。

相比而下,我觉得apr还好点,其实我需要的只是一个机制,而不是一个完整的策略,这是unix的哲学。如果仅就异步通讯来说,我觉得linux.epoll是最好的,简单、直接、有效,如果在每个平台上都有epoll可用,所有其它封装在我看来都是多余的了。

proactor真的就比reactor高效吗?它更多的是一种策略,据说Windows的操作系统级IOCP是用线程池实现的,它能高效到哪里去?

 

process–>thread–>coroutine

阅读更多关于《process–>thread–>coroutine》

在现实世界中,基本是是按着这样的顺序演化:process–>thread–>coroutine/fiber

其实是一个context切换开销从大到小的演化,process切换开销最大,需要切换地址空间,所有的CPU状态,所有其他资源

thread切换只需要切换CPU状态,当然是大部分的CPU状态,而coroutine切换,只需要切换很少的CPU状态,而且全部都在用户地址空间运行,不需要到内核空间。

当然,切换coroutine的开销还是比一次函数调用大很多,其实函数调用也是一个cpu状态的切换,不过这个状态要少得多,在x86 windows 上,甚至不必保存所有的寄存器状态(EAX/ECX/EDX在函数调用之间就不用保证,EAX保存返回值),有些调用甚至通过寄存器传递参数……比起coroutine,太微不足道了。

coroutine其实也可以看成是一个保留了以前调用状态(另一个堆栈帧)的函数调用,在寄存器很多的系统上(如Itanium),切换寄存器状态的开销还是比较大的,如果哪一天大家又开始嫌coroutine也太慢,那怎么办?

原来Fiber就是Coroutine

阅读更多关于《原来Fiber就是Coroutine》

  前段时间自作聪明的还以为自己发现了一个完美的解决异步IO的方法,还真太把自己当回事了。人家已经早有这个办法了,还有个学名,叫做Coroutine,在异步IO中的应用也已经非常多了,我真是太孤陋寡闻了。

异步通讯中使用纤程(Fiber/UserSpaceThread)

阅读更多关于《异步通讯中使用纤程(Fiber/UserSpaceThread)》

在异步通讯中,一般使用一个线程来select/poll/epoll,收到信号后,解码消息头,或者整个消息,然后将相应的fd交给其他线程处理。这看上去的确是个很好的办法,但是…… 继续阅读