怎么用boost的condition等待多个条件

2009年2月24日

一直没明白怎么用condition等待多个条件,就象win32下WaitForMultipleObjects那样,
看了这个 http://lists.boost.org/Archives/boost/2001/10/18407.php
一下子豁然开朗,condition其实是一个“复合条件”,强!

--- In boost_at_y..., mf_dylan_at_y... wrote: 
> I sent this as a mail to Bill Kempf first, he suggested I repost it 
> here: 

The main reason for the request was that the answer would benefit 
others. 

> One thing though, how would I go about waiting on multiple 
> conditions? This is actually the norm in much of my multi-thread 
> work...most of the time is spending waiting on various threads and 
> conditions, usually one of them is a "shutdown" event, another is a 
> checking for work to do etc. etc. Doesn't seem to be any easy way 
of 
> achieving this unless I'm missing something. 

Windows is one of the few threading systems I'm aware of that allow 
you to "wait" for multiple synchronization objects at once. However, 
the lack of this ability shouldn't really be an issue in any real 
world examples because of the nature of condition variables. See, a 
condition, unlike a Win32 event, relies on three components: the 
condition itself, some external shared data "state" and a mutex to 
insure proper synchronization between the three components. It's the 
shared data that's the key here. Taking your description and 
providing two example implementations, one in Win32 and one in 
Boost.Threads, should illustrate this. 

// Win32 

struct ThreadData 
{ 
   HANDLE shutdown_event; 
   HANDLE do_work_event; 
}; 

// signature not accurate, but this simplifies example 
void do_thread(ThreadData* data) 
{ 
   // Note that there are serious race conditions in the following 
   // code... this is for illustrating how to handle multiple 
   // "events" in both styles only, not for proper threading 
   // techniques on Win32. 
   for (;;) { 
      HANDLE handles[2]; 
      handles[0] = data->shutdown_event; 
      handles[1] = data->do_work_event; 
      DWORD result = WaitForMultipleObjects(2, handles, FALSE, 
INFINITE); 
      if (result == WAIT_OBJECT_0) { 
         // Handle shutdown_event; 
      } 
      else if (result == WAIT_OBJECT_0 + 1) { 
         // Handle do_work_event; 
      } 
      else { 
         // Handle error 
      } 
   } 
} 

// Boost.Threads 

struct ThreadData 
{ 
   boost::mutex mutex; 
   boost::condition condition; 
   bool shutdown; 
   int pending_work; 
}; 

void do_thread(ThreadData* data) 
{ 
   // Again, thread synchronization will need adjusting for real 
   // code. 
   boost::mutex::scoped_lock lock(data->mutex); 
   for (;;) { 
      while (!data->shutdown && data->pending_work == 0) { 
         data->condition.wait(lock); 
      } 
      if (data->shutdown) { 
         // data->condition.notify_*() was called because another 
         // thread was requestion we shutdown. Handle this "event". 
      } else { 
         // There's work pending, so do it. 
         data->pending_work--; 
      } 
   } 
} 

A single condition variable has been used for waiting, but we are 
waiting on multiple states, which achieves the same effect as waiting 
on multiple Win32 events. 

> If some method for doing this was provided it would be arguably 
> essential to be able to also wait on other threads terminating (and 
> ideally other processes, but this is probably out of the scope of 
> boost threads). I had thought some time back about how something 
> like this could be possible using an extendable scheme where 
objects 
> provide "waitable" handles that can be, well, waited on! I'm not 
> exactly sure how you could go about doing this with pthreads to be 
> honest, it doesn't seem to have anything close 
> to "WaitForMultipleObjects". I thought about doing it with select, 
> but never got around to experimenting enough to be able to 
determine 
> if that was viable. 

This would be done in pthreads the same as illustrated above for 
Boost.Threads. The open nature on what the "state" is in a monitor 
pattern using condition variables allows for everything that WFMO 
gives us in Win32, though the plumbing for implementing a "waitable 
handle" is obviously going to be a little more complex since it's not 
built in. However, I've never had code that actually could benefit 
from "waitable handles" in Win32. The only time I've employed WFMO 
has been with mutliple events, and the condition variable allows for 
this pattern with out a need for "waitable handles". 

Bill Kempf 
> Dylan 


新闻组里的大牛们总是精力充沛,不厌其烦得回答各种初学者的问题,而且,往往是非常详细,不得不佩服。初学者提问的时候也要注意新闻组的礼貌,建议去看看《提问的艺术》,节约大牛的时间是对他们最大的尊重。

未分类

解决WTL和ATL头文件的冲突

2009年2月24日

WTL提供了CString,CRect,CPoint和CSize,可能后来版本的ATL也提供了,
WTL作者推荐使用ATL的实现,所以: 

#include <atlstr.h>	// CString
#include <atltypes.h>	// CRect,CPoint,CSize
注意,这两行必须放在
#include <atlbase.h>
的上面,然后,这个放最后好了:
#define _WTL_NO_WTYPES
#define _WTL_NO_CSTRING
#include <atlmisc.h>

代码片段 ,

备忘录之 - Windows上编译使用stlport的boost

2009年2月22日

修改 E:\Libraries\boost_1_38_0\tools\build\v2\user-config.jam

# using msvc : 8.0 ;
前的注释符去掉

# using stlport : 5.2.1 : E:/Libraries/STLport-5.2.1/stlport E:/Libraries/STLport-5.2.1/lib ;
前的注释符去掉,再填入路径,版本等。注意,路径必须用反斜杠,否则链接会失败。头文件路径和库文件路径中间不能加冒号,这个和boost build的文档有些出入。

编译:
bjam –toolset=msvc stdlib=stlport –build-type=complete stage

备忘录

备忘录之 - Windows上编译stlport5.2.1

2009年2月22日

如果要使用它提供的iostream库的话,才需要编译

我的环境是WinXP,VC8,boost1.38

修改 stlport/stl/config/user_config.h,把 #define _STLP_USE_BOOST_SUPPORT 1 的注释去掉

运行VC的Cmd,进入stlport目录,执行:
configure msvc8 -p winxp –use-boost “E:\Libraries\boost_1_38_0″ –extra-cxxflag /Zc:wchar_t

进入 build/lib 目录,运行 nmake /fmsvc.mak clean install
因为指定了 –use-boost “E:\Libraries\boost_1_38_0″,会有编译错误,需要改一下stlport的代码:
编辑 stlport\stl\type_traits.h

#ifdef _STLP_USE_BOOST_SUPPORT
#  include &lt;stl/boost_type_traits.h&gt;
#  include &lt;boost/type_traits/add_reference.hpp&gt;
#  include &lt;boost/type_traits/add_const.hpp&gt;
#  include &lt;boost/type_traits/remove_const.hpp&gt;   &lt;-- 加入这行
#endif /* _STLP_USE_BOOST_SUPPORT */

再编译,通过!

记得把头文件路径加入VC IDE的头文件搜索路径的最前面
还有lib文件搜索路径也加好

把bin目录里的 stlport.5.2.dll, stlportd.5.2.dll, stlportstld.5.2.dll 复制到系统path的目录里去。

完成。

备忘录

其实,coding比design难多了

2009年1月4日

coding,是程序员的真本事,用无数的时间和努力换回来的宝贵实战经验,而design能力,只是coding过程中的一个副产品。

未分类

类继承是一个根本的错误

2009年1月4日

类继承是一个非常强的耦合关系,这根本是一个错误,或许在C++等静态语言里有它存在的理由(继承在C++里也已经越来越不重要了,将来concept会让继承从此消失的),那么在动态语言Python里就根本不应该支持。在OO时代,继承有它的地位,但不久的将来,它就会退出历史的舞台。

本来,单继承就是不足以表达面向对象的,所以有多重继承的需要,但多重继承又有很多的问题,以至于是否要支持多重继承一直是语言设计的一个争议点。其实问题的本质就在于,本来就不应该有继承。长久以来,人们都喜欢用树结构来组织分类,分类生物,分类文件目录,分类你们的网址书签,但你们不觉得别扭吗?有很多东西是可以分类到多个分支下面的,于是终于有人想明白了,发明了用tag分类,这个才是最自然的,其实tag就是concept。

瞄了一下Trac的插件架构设计,还有SharpDevelop,Eclipse等的插件架构,核心都是一样的 — 扩展点,挂接点,等等,不管叫什么吧,其实就是接口,就像我前面说的,设计的根本关键就是接口。

或许用接口这个词不太合适,给人一种具体语法的错觉,叫concept应该更合适,就是一个约束,一个契约。

这方面动态语言有天生的优势,实现这种插件架构即优雅又简单,用C++的话就要拼了老命了,最终出来的还是个畸形,Sigh。

未分类

备忘录之 - Windows上安装Trac

2009年1月3日

主页:
http://trac.edgewall.org/

看他主页说明,你先要装好python2.5(目前Trac不支持2.6和3.0),easy_install 和 sqlite3.3.4以上版本

然后执行 easy_install Trac 即可

然后在cmd运行比如:
trac-admin D:\TestTrac initenv
然后他会提问
项目名:比如叫 Project1
然后会问数据库连接串,如果不需要设置,直接回车即可,
版本控制的名字,如果不需要设置,直接回车即可,
repos的位置,如果不需要设置,先直接回车,也可以以后设。

最后可以看到:

You may now configure the environment by editing the file:
D:\TestTrac\conf\trac.ini

If you’d like to take this new project environment for a test drive,
try running the Trac standalone web server `tracd`:

tracd –port 8000 D:\TestTrac

Then point your browser to http://localhost:8000/TestTrac.
There you can also browse the documentation for your installed
version of Trac, including information on further setup (such as
deploying Trac to a real web server).

在 D:\TestTrac 下面生成了很多文件目录

端口用7000好了,试试
tracd –port 7000 D:\TestTrac

然后浏览
http://localhost:7000/TestTrac

http://localhost:7000/
列出所有项目,比如现在只有一个:Project1

如果只需要从本地连接,加个参数安全些
tracd –hostname=localhost –port 7000 D:\TestTrac

停止trac服务器要用ctrl-break,别用ctrl-c,会遗留python进程不退出。

安装好后,需要创建认证文件,进入环境目录,D:\TestTrac
运行 htpasswd -c D:\TestTrac\htpasswd username
好像Apache带了这个工具,如果没有装Apache,可以用在线工具生成,比如
http://www.htaccesstools.com/htpasswd-generator-windows/
Trac的文档里也有生成器python源码,可以自己试试 

启动:
tracd -p 7000 –basic-auth=TestTrac,D:\TestTrac\htpasswd,D:\TestTrac D:\TestTrac

本地svn仓库路径在 conf\trac.ini 文件里设置,比如:
repository_dir = d:\testtracsvn

备忘录

发现一个不错的开源战棋游戏

2008年12月31日

是个回合类的战棋游戏,有点意思,而且它是开源的!
http://www.wesnoth.org/

中文论坛
http://www.wesnoth.cn/index.php

wesnoth-14-7-175 wesnoth-14-2-175 

游戏里文字有中文版。

未分类 ,

用py2exe打包发布python程序

2008年12月28日

主页:
http://www.py2exe.org/

下载:
http://sourceforge.net/project/showfiles.php?group_id=15583

教程:
http://www.py2exe.org/index.cgi/Tutorial

其他参考资料:
http://www.luohuizhu.cn/blog/?action=show&id=544
http://onlypython.group.javaeye.com/group/blog/63190
http://jinheking.javaeye.com/blog/165057

我总结一下:
安装了py2exe后 ,写个文件setup.py

1
2
3
4
from distutils.core import setup
import py2exe
 
setup(console=['hello.py'])

hello.py就是你要发布的程序,然后执行 setup.py py2exe
就生成了要发布的dist目录,另一个build目录是临时文件可以删除。

然后就可以直接运行 hello.exe 了,不过会有一个console窗口出现,如果你的程序是有GUI的,
把 setup(console=['hello.py']) 里的 console 改成 windows 即可。

执行 setup.py py2exe –help 可以看看其他的参数,
比如,加上 -b1 参数可以把大部分文件都压缩到library.zip文件中去,不过注意,执行前先删除老的dist等目录。
但有个小问题,这个zip文件用winrar打开会出错,执行倒是没什么问题。
默认是-b3,试了下-b2,结果是留了python25.dll在外面。

再有比如-c参数,会压缩zipfile,生成的dist是小了很多,但第一次运行时会有点慢吧,要解压。

还有个-O参数设置优化等级,默认是-O0关闭的,-O1是优化python生成的字节码,-O2是在-O1的基础上把docstring去掉。

还有一些更有用的功能,可以输入setup.py –help 和 setup.py –help-commands 查看

Python学习

What is FastCGI for PHP

2008年12月28日

[转]自某国外主机帮助

FastCGI for PHP

FastCGI for PHP makes all your PHP applications run through mod_fcgid instead of mod_suphp. FastCGI applications are fast because they’re persistent. There is no per-request startup and initialization overhead. This makes possible the development of applications which would otherwise be impractical within the CGI paradigm (e.g. a huge PHP script, or an application which requires a connection to one or more databases).

Benefits:

  • PHP scripts will run faster. The PHP interpreter is loaded into memory rather than calling from storage for every hit, greatly improving performance of your scripted site.
  • You will use less Server Resources. Since the server does not have load the PHP interpreter for each hit, you will be able to accommodate a higher traffic site without exceeding your CPU quota.
  • NO modifications to your existing code are required. Everything you currently run will work with FastCGI for PHP.

Potential Problems:

  • You will only have one php.ini file available for all subdirectories (/home/USERNAME/public_html/php.ini). This is necessary to help optimize the website code as much as possible. If you need multiple php.ini files to accommodate different scripting needs, you can disable FastCGI for PHP on any of your subdirectories while leaving the rest of the account enabled for performance. Please contact support if you need to do this.
  • There can be a few minute delay in any updates you make to your PHP environment (ie, php.ini changes). Since your php.ini is loaded into memory for greater speed, every hit does not re-read it from storage.

未分类

[3,534,5,777]