posts - 319, comments - 22, trackbacks - 0, articles - 11
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

上一次关注Qt Lighthouse是在6月初,可是现在都8月底了。时间真快...

Lighthouse 是 QPA(Qt Platform Abstraction) 项目的名字,它使得将Qt移植到新的平台变得比较简单。尽管现在它已经完全融入到了Qt主干代码中,lighthouse作为独立项目已经不复存在了,但本文中,我们继续使用这个名字(虽然已不太恰当)。

QPA 抽象了什么?

不妨看看QPA前后,有何不同:

之前

考虑一下,传统的Qt是如何实现图形界面的夸平台:

  • 针对不同的窗口系统(WS)定义相应的宏: Q_WS_*

Q_WS_X11
Q_WS_MAC
Q_WS_QWS
Q_WS_WIN
Q_WS_S60
  • 代码中夹杂大量的编译预处理指令 (处理小段)

#if defined(Q_WS_X11)
...
#elif defined(Q_WS_MAC)
...
#elif defined(Q_WS_WIN)
...
#endif
  • 各个窗口系统相关的代码文件 (处理大段)

qapplication_x11.cpp
qapplication_win.cpp
qapplication_s60.cpp
qapplication_mac.mm
qapplication_qws.cpp
...
qwidget_win.cpp
qwidget_qws.cpp
qwidget_mac.cpp
qwidget_x11.cpp
...
  • src/gui/kernel.pri 等工程文件内,控制哪些文件参与编译

win32 {
...
}
symbian {
...
}
unix:x11 {
...
}

这一切这意味这什么??

如果我们想在这个基础上支持一个新的窗口系统,比如wayland,需要

  • 添加平台相关的宏,代码中针对该窗口再扩充 #if #elif #endif

  • 添加平台相关的文件,扩充 **.pri 文件使其融入Qt
  • ...

总之,需要对Qt的代码进行大量的修改。这一切使得将Qt移植到新的窗口系统中,变得不是那么容易。

之后

QPA 定义了一套接口,而后,将窗口系统相关的代码放到插件中:

  • src/plugins/platforms/xlib/*
  • src/plugins/platforms/wayland/*
  • src/plugins/platforms/cocoa/*

这时,如果我们想支持一个新的窗口系统,怎么办?只需要编写一个新的插件,而Qt自身的代码则不需要任何改变。

(当然,编写插件本身还是很有难度的,哈...)

QPA源码结构

为了使插件能供工作,Qt中需要提供有相应的加载接口,在Qt源码中搜索*_qpa.h*_qpa.cpp *_qpa_p.h 即可找到所有(fixme)和 qpa有关的代码:

  • QTDIR/src/opengl
    • qgl_qpa.cpp
  • QTDIR/src/gui
    • painting
      • qcolormap_qpa.cpp
      • qpaintdevice_qpa.cpp
    • image
      • qpixmap_qpa.cpp
    • egl
      • qegl_qpa.cpp
    • kernel
      • qplatformintegrationplugin_qpa.cpp
      • qplatformcursor_qpa.cpp
      • qwidget_qpa.cpp
      • ...
    • text
      • qfontengine_qpa.cpp
      • qfontengine_qpa_p.h
      • ...

可以看到代码集中在 gui/kernel 部分;除此外,和字体相关gui/text,和绘图相关gui/painting、gui/image、gui/egl,和opengl相关

QPA结构

QPlatformIntegration

这个应该算是 QPA 的核心了,

  • 它是QApplication(准确地说是QApplicationPrivate)的成员

class Q_GUI_EXPORT QApplicationPrivate : public QCoreApplicationPrivate
{
...
    static QPlatformIntegration *platform_integration;
...
  • 在初始化QAppliction时它会被创建

QApplication::QApplication()
  QApplicationPrivate::construct()
   qt_init()
     init_platform()
       QPlatfromIntegrationFactory::create()
  • 它是所有窗口系统相关函数的入口点

class Q_GUI_EXPORT QPlatformIntegration
{
public:

GraphicsSystem functions

virtual QPixmapData *createPixmapData()

virtual QPlatformWindow *createPlatformWindow()

virtual QWindowSurface *createWindowSurface()

Window System functions

virtual QList<QPlatformScreen *> screens()

virtual void moveToScreen()

virtual bool isVirtualDesktop()

virtual QPixmap grabWindow()

Deeper window system integrations

virtual QPlatformFontDatabase *fontDatabase()

virtual QPlatformClipboard *clipboard()

...

这样一来:

当你在程序中

它会向QPlatformIntegration请求

使用QWidget时

给我一个窗口(QPlatformWindow)及绘图区域(QWindowSurface)

使用QPixmap时

给我一个位图的后端(QPixmapData)

使用QFont时

给我字体数据信息(QPlatformFontDatabase)

使用QGLWidget时

给我一个窗口

...

...

QPlatformWindow 与 QWindowSurface

QPlatformWindow

窗口
负责窗口的几何尺寸
可以是另一个窗口的子窗口

QWindowSurface

窗口绘图区域(drawing area of a window)
它来决定使用哪一个paintEngine
将像素Push到屏幕上

相对而言,QPlatformWindow 出现的比较晚一点(见Say hello to QPlatformWindow一文)之所以。之所以分离开来,原因见Remodelling the Lighthouse

QPlatformScreen

  • 代表屏幕(显示器)
  • 它提供的api对应用程序来说是只读的
  • 用来计算分辨率 dpi

class Q_GUI_EXPORT QPlatformScreen : public QObject
{
...
    virtual QRect geometry() const = 0;
    virtual QRect availableGeometry() const {return geometry();}
    virtual int depth() const = 0;
    virtual QImage::Format format() const = 0;
    virtual QSize physicalSize() const;

QPixmapData

为什么要有这个东西?

通常我们似乎都不怎么区分QImage和QPixmap,尽管在Manual中很大的篇幅在描述这二者的区别。

设计目的和用途(一个是IO和像素操作,一个是屏幕显示):

  • QImage is designed and optimized for I/O, and for direct pixel access and manipulation
  • while QPixmap is designed and optimized for showing images on screen.

典型的用途:

  • Typically, the QImage class is used to load an image file, optionally manipulating the image data, before the QImage object is converted into a QPixmap to be shown on screen.
  • Alternatively, if no manipulation is desired, the image file can be loaded directly into a QPixmap.

与QImage不同,QPixmap 是平台相关的

  • Note that the pixel data in a pixmap is internal and is managed by the underlying window system.

于是它的后端需要由各个窗口系统来提供也就不足为奇了。

QPlatformFontDatabase

提供字体信息

详见Fonts in Lighthouse一文。

其他

  • QPlatformClipboard
  • QPlatformCursor
  • ...

同前面几个一样,从名字上容易看出是做什么的。

参考

posted @ 2011-09-15 21:24 RTY 阅读(854) | 评论 (0)编辑 收藏

http://blog.csdn.net/dbzhang800/article/details/6686859


  • 作为一个Qt的粉丝,对将于明年发布的Qt5充满了期待。可是想想Qt5将发生的巨大变化,心底又有点不安。Qt5到底会变成什么样呢?

看看近期Qt5的一些大动作:

  • 从 QtCore中移除 QSettings以及对QSettings的依赖(创建独立的模块?)

  • 从 QtCore中移除 QtConcurrent(创建独立模块?)

  • 将 QJSEngine 和 QDeclarativeEngine 放入 QtCore

  • 从 QtGui 中分离出 QtPrintSupport,保留pdf生成功能

  • QtCore 添加 zip 文件的读写功能

  • ...

Qt5 结构

Qt Essentials

在所有平台可用

Qt Tools

Qt的不可分割的组成部分,在所有桌面平台可用

Qt Add-Ons

可跨平台,也可不跨

其他模块和工具

第三方?

Qt5 的基础模块(Qt Essentials)

Qt Core

 

Qt Network

可能会集成到 Core

Qt Gui

除去所有QWidget相关的类以后的部分

Qt OpenGL

可能会被合并到其他模块

Qt Quick2

 

Qt Test

 

Qt Sql

 

V8 JavaScript engine

 

Qt DBus

由于依赖问题,必须被包含进来

Qt WebKit

提供新的底层C++和QML的接口

Qt MultimediaKit

 

来自Qt mobility的一些模块

初期可能还不会包含进来

Qt5 的核心将是 Qt Quick,qml和javascript将成为一等公民。这些模块中变化最大的当属 Gui 模块了,GUI结构进行了彻底的更新:

  • SceneGraph, 什么东东呢?不太了解。似乎:“Scene Graph”是一种组织场景数据的方法,它把数据放进一个层次结构里。

  • OpenGL, Qt5将依赖OpenGL 2

  • lighthouse(QPA),各个平台下图形系统的移植靠它实现,不过现在好像还没看到Win32插件的影子。

同时 QWidget 相关内容将独立成为QtWidget 模块,与打印相关内容,独立出来成为QtPrintSupport,...

但是,这并不是说这部分被废弃了。之所以不在Qt Essentials内,是因为并不是所有平台都需要它。对于桌面平台来说,QtWidget 和其他模块一样,是一等公民!!

  • We want to send the correct message to the users of QWidget classes: they are 1st class citizens in the desktop environment, but not necessarily available in the embedded or mobile environments

Qt附加组件(Qt Add-Ons)

在Qt5中,尽管 Qt Quick 是Qt的中心,但是Qt5仍将一如既往支持原生C++ Qt,而且不想与现在Qt4开发的代码分裂。Qt4中的一些模块在Qt5中被放入Qt Add-Ons中。

  • Qt 5 continues to offer all of the power of native Qt C++, and we don’t want Qt 5 to be disruptive for existing code developed for Qt 4.

QWidget 模块

模块成熟级别:完成(Done)
不再添加新特性或进行性能优化

Xml

XmlPatterns

Script 和 Scripts Tools

ActiveQt

Svg

模块成熟级别:废弃
QtWebKit提供Svg Full支持

Mobility中的一些模块

 

Qt Quick components模块

 

3D

 

graphics effects

 

还有些东西没看到哈,比如:

phonon

phonon由KDE社区继续维护,Qt建议使用 QtMultimediaKit

Qt Multimedia

从Qt4.8开始,废弃,建议 QtMultimediaKit

Qt3 Support

废弃

参考


posted @ 2011-09-15 21:23 RTY 阅读(762) | 评论 (0)编辑 收藏

最近读了《卓有成效的程序员》,感觉收获颇大。这是一本写给程序员的难得的好书。书中大都是一些浅显的道理,但作者将这些东西加以收集、归纳、总结,并最终成书。作者为了收集各种提高效率的工具和方法,东奔西走,可谓费了一番苦心。

我觉得此书第一部分总结的一些法则非常好,我提取了一下:

法则: 

1.加速法则

    关注本质,而非形式

    一个应用程序列表的有用程度与它的长度成反比 

    程序员的很多时间都浪费在找东西上 

    华而不实的东西中看不中用

    键盘输入总比导航快

    首选键盘而非鼠标

    地址栏是Windows资源管理器界面中最高效的部分

    花点时间来学习你手边的所有隐藏的快捷键

    环境切换会消耗时间

    成批复制粘贴要比反复多次复制粘贴快

    忘记历史就意味着你得再输入一遍

    嵌入图形化工具的命令提示符让你鱼与熊掌兼得

    在上下文中学习IDE快捷键,而不要去背长长的列表

    当你第二次输入一个复杂结构时,将它做成模板

    如果要对多行文本做同样的操作,就应该找出其中的模式,并把它记录为一个宏

    不要总是重复输入相同的命令

    每天花一点点时间来使每一天都更高效 

2.专注法则

    精力越集中,思维越缜密

    排除干扰:隔离策略,关掉不需要的提示,创造安静时间  

    草堆越大,从中找到一根针就越难

    不要问文件树,要搜索

    使用多显示器

    虚拟桌面可以让原本杂乱无章的一大堆窗口变得整洁 

3.自动化法则

    不要重新发明轮子

    用Selenium浏览网页

    不要浪费时间动手去做可以被自动化的事情

    用Windows Power Shell替代批处理文件

    驯服Subversion命令行

    以创造性的方式解决问题,有助于在将来解决类似的问题

    是否应该自动化的关键在于投资回报率和缓解风险

    研究性的工作应该放在时间盒里做

    别给牦牛剪毛 

4.规范性法则

    对于任何你不自己去构建的东西,只在版本控制中保存一份副本

    使用标准的构建服务器

    通过复制粘贴来复用是邪恶的,不论你复制粘贴的是什么

    利用虚拟平台使项目依赖标准化

    不要让对象 - 关系映射工具(O/R映射器)违反规范原则 

    通过扩展。开放类(open class),或者部分类(partial class) 来为生成的代码增加行为

    始终保持代码和数据结构的同步

    过时的文档比没有文档更糟,因为它会主动误导你

    任何需要费劲创造的东西,都让它的创造者欲罢不能

    白板 + 数码相机强过任何CASE工具

    尽量生成所有技术文档

    重复是软件开发中最大的阻力 

工具:

书中,还提到了大量的提高效率的工具,都是非常不错的。相信很多人都有自己的一个列表,下面是我电脑中必不可少的几款软件:

    1. FireFox 及其各类插件

    2. Launchy启动加速器

    3. Total Commander

    4. ClipX多重剪切板

    5. EmEditor文本编辑器 

    6. Vistual Studio的VA插件

    7. Search And Replace

    8. Everything

    9. Miranda IM

    10. .... 

感触: 

1. 愤怒的猴子 

在书中的第二部分,提到了很多实践相关的内容。让我感触最深的是“愤怒的猴子”的故事:

早在20世纪60年代(那时候科学家们可以做任何疯狂的事情),行为科学家们进行了一项实验。他们把五只猴子和一架活梯放在一间屋子里,并在天花板上挂了一串香蕉。这些猴子很快就想到它们可以爬上梯子去吃香蕉,但每当它们靠近活梯的时候,科学家们就用冰水浸满整个屋子。我想你能猜到会发生什么:一群愤怒的猴子。很快,再没有一只猴子会去靠近那个梯子了。

之后,科学家们将其中一只猴子替换成另一只没有忍受过冰水折磨的新猴子。这只新猴子所做的第一件事就是直奔那架梯子,但当它这么做时其他所有猴子都痛打它。它不明白为什么,但很快就学乖了:不要去靠近那架梯子。科学家们逐渐将最初的那些猴子都替换成新猴子,直到这群猴子中谁都没有被水浸泡过,然而它们还是会去攻击任何靠近梯子的猴子。

这说明了什么?软件项目中许多惯例之所以存在,就因为”我们一直是那样做的“。换句话说,是因为愤怒的猴子。

我们小组在制定C++相关的代码规范时就遇到过无数类似的问题。比如,在制定变量的命名规范时,我们针对是否采用匈牙利命名法争论了很久。有的人认为, 几乎以前看到的所有C++代码都采用了匈牙利命名法,甚至,微软定义的所有API都使用了此类命名法。刚开始,我也是有同样的疑惑。

后来,我们经过仔细分析C++匈牙利命名法由来,渐渐感觉我们就是那些愤怒的猴子,盲目跟从前人的方式,缺乏打破传统的勇气。C++有着其特殊的历史原因,很多标准一直沉淀下来并很少改变。我们再看看后来新生的那些编程语言,C#, Python…… 都抛弃了匈牙利命名法,同时再看看现在C++前沿的C++ 0x以及现在出版的一些书中,也渐渐放弃了对匈牙利命名法的使用。因为类型的意义在对象模型中越来越弱化。因此,最后我们放弃了匈牙利命名法这个老古董。 

2. 敏捷开发

这本书带有强烈的ThoughtWorks色彩,敏捷的思想贯穿全书,包括测试驱动设计,白板,结对编程。这也让我对敏捷产生了更加强烈的兴趣。 其中有一段测试驱动开发TDD的一段故事:

记得第一次和一些已经习惯于单元测试的开发人员一起动手开始修改代码时,我也是非常紧张,因为大量的修改往往会破坏很多东西,但他们看起来丝毫没有犹豫。逐渐地,我也放下心来,因为我慢慢地认识到:有了测试的保证,完全可以放心大胆地去修改代码。” 

3. 有趣的故事 

书中还有一些有趣的故事,比如作者的一个朋友在和别人结对编程时,为了养成同伴使用快捷键的习惯,每当同伴未使用快捷键时,他都会要求将操作撤销,然后要求使用快捷键再重复操作3次。然后,在其凶狠的眼神中,同伴很快掌握了快捷键。 

总结:

这本书很薄,蕴藏的道理却不少,相信每个读过它的人都会从中收获。读过之后,我们不应该局限于书中提到的某些小技巧, 或是书中某一个细节,毕竟,提供效率的方法有很多很多,法则也有很多很多,一本书很难将其穷举完。我们应该从书中吸取其思想,并在实际工作和学习中不断总结,做一个真正的“卓有成效的程序员”!

posted @ 2011-09-15 07:36 RTY 阅读(259) | 评论 (0)编辑 收藏

     摘要: http://www.codeproject.com/KB/Parallel_Programming/Threading_Blocks.aspxIntroductionThe Intel TBB was released by Intel during their movement to enhance system performance by cores, rather t...  阅读全文

posted @ 2011-09-15 07:05 RTY 阅读(614) | 评论 (0)编辑 收藏

http://www.cnblogs.com/coderzh/archive/2010/09/16/Pyjamas-python-write-javascirpt.html

Pyjamas - 用python代替javascript编写基于浏览器的应用

如果能用python代替Javascript编写基于浏览器的应用,该有多好啊。但是,Javascript是唯一一种能在浏览器里执行的语言(Flash或Silverlight除外)。换个思路,先用Python编写代码,然后在通过编译器转为为Javascript脚本,这样确实是可行的。嗯,已经有人这么干了,就是这个:Pyjamas

Pyjamas的介绍:

Google 的 Web Toolkit (GWT) 让我们能够完全用 Java™ 代码开发具有 Ajax 功能的 Rich Internet Application (RIA)。可以使用丰富的 Java 工具集(IDE、重构、代码补全、调试器等等)开发出可以部署在所有主流 Web 浏览器中的应用程序。在 GWT 的帮助下,可以编写出在浏览器中运行但是表现与桌面应用程序相似的应用程序。

和GWT类似,Pyjamas是一个跨浏览器API,有了它,你可以使用Python编写客户端功能。 使用Pyjamas的优点是你可以用 Python代替HTML和JavaScript编写网络程序,你可以重复使用和导入类和模块。 此外AJAX库还可以解决互用性问题,不用担心程序在IE6, IE7, Firefox, Safari, Opera等浏览器上的兼容问题。

 

 

是不是觉得很酷呢?pyjamas有一个演示页面,里面有多个的效果。 

比如:

火星登陆游戏:http://pyjs.org/examples/asteroids/output/Space.html

邮件客户端:http://pyjs.org/examples/mail/output/Mail.html 

GWTCanvas:http://pyjs.org/examples/gwtcanvas/output/GWTCanvasDemo.html 

(HTML5 Canvas?? 有人讨论这个问题在这里


posted @ 2011-09-15 06:55 RTY 阅读(461) | 评论 (0)编辑 收藏

     摘要: http://www.cnblogs.com/coderzh/archive/2010/11/29/lupa.htmlLupa - Python中调用LuaLupa将LuaJIT集成到了Python模块中,可以在Python中执行Lua代码。 比较有意思,也许以后用的着,记录一下。基本用法:>>> import lupa>>> fr...  阅读全文

posted @ 2011-09-15 06:52 RTY 阅读(1353) | 评论 (0)编辑 收藏

网址:http://code.google.com/p/googletest/

引文
http://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html

玩转Google开源C++单元测试框架Google Test系列(gtest)(总)

前段时间学习和了解了下Google的开源C++单元测试框架Google Test,简称gtest,非常的不错。 我们原来使用的是自己实现的一套单元测试框架,在使用过程中,发现越来越多使用不便之处,而这样不便之处,gtest恰恰很好的解决了。

其实gtest本身的实现并不复杂,我们完全可以模仿gtest,不断的完善我们的测试框架, 但最后我们还是决定使用gtest取代掉原来的自己的测试框架,原因是:

1.不断完善我们的测试框架之后就会发觉相当于把gtest重新做了一遍,虽然轮子造的很爽,但是不是必要的。

2.使用gtest可以免去维护测试框架的麻烦,让我们有更多精力投入到案例设计上。

3.gtest提高了非常完善的功能,并且简单易用,极大的提高了编写测试案例的效率。

gtest的官方网站是:

http://code.google.com/p/googletest/

从官方的使用文档里,你几乎可以获得你想要的所有东西 

http://code.google.com/p/googletest/wiki/GoogleTestPrimer

http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide 

如果还想对gtest内部探个究竟,就把它的代码下载下来研究吧,这就是开源的好处,哈! 

官方已经有如此完备的文档了,为什么我还要写呢?一方面是自己记记笔记,好记性不如烂笔头,以后自己想查查一些用法也可以直接在这里查到,一方面是对于不想去看一大堆英文文档的朋友,在我这里可以快速的找到gtest相关的内容。

下面是该系列的目录:

1.玩转Google开源C++单元测试框架Google Test系列(gtest)之一 - 初识gtest

2.玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

3.玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制

4.玩转Google开源C++单元测试框架Google Test系列(gtest)之四 - 参数化

5.玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试 

6.玩转Google开源C++单元测试框架Google Test系列(gtest)之六 - 运行参数

7.玩转Google开源C++单元测试框架Google Test系列(gtest)之七 - 深入解析gtest

8.玩转Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架


额外篇:

1.gtest中如何跳出当前测试案例

2.编写优美的GTest测试案例

3.gtest 参数化测试代码示例 (内含完整工程示例)

作者:CoderZhCoderZh的技术博客 - 博客园
微博:http://t.sina.com.cn/coderzh 
出处:http://coderzh.cnblogs.com
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。


posted @ 2011-09-15 06:40 RTY 阅读(1460) | 评论 (0)编辑 收藏

刚接触单元测试时,我实在是搞不懂这种测试到底有多大的意义,无非都是一些简单的ASSERT,但近年积累一些经验教训之后我才发现,单元测试这玩意儿真的是一种保证程序质量的强有力手段。

为什么这样说?举个最典型的例子,无论是开发新功能还是维护老程序,都不可避免的要反复修改某些代码,那该怎么保证修改的代码不会引入新的问题?如果你说你用人品担保,那我服了。我们应该需要一种可靠的手段来保证修改一个BUG不会引入两个三个BUG,或者不会让之前正确的功能出错,甚至是不会引入之前已经修改过的其它BUG。测试无疑是一种很好的手段,在没掌握其它更好的方法之前,很多人喜欢用人工测试,即编译 – 运行 – 输入典型值 – 看程序运行结果 – 如果出错 – 修改后再编译……从长远来看,这种测试方法的缺点很明显:1、耗时耗力,每次修改代码后都需要人工重复测试所有的典型情况;2、容易出错、漏测,人脑太复杂,你很难记得几个月前的那个BUG到底是什么情况,因此没法测试,久而久之,N久前的那个BUG可能又神不知鬼不觉的重现了。相比之下,单元测试的优点就凸显出来了,把需要测试的典型情况编写为测试代码,然后编译运行即可完成自动化的测试,当发现BUG后,把它添加到测试用例,不仅可以提高测试覆盖率,还能保证以后不会再次引入同样的BUG,有了足够的单元测试(覆盖率),你就可以理直气壮的说代码没问题!当然引入单元测试会在前期花费不少的时间来编写测试代码,但相应的也会大大减少后期的维护工作,最主要的是能可靠的提高程序的质量,所以是值得的,甚至是必要的。(如果你编译过开源的Google Chromium浏览器,你会发现测试代码就占了不少,光是编译测试代码就得花很长的时间)

除了上面说的优点外,单元测试还有一些其它的好处,比如帮你理清设计。一些人反对单元测试就是因为说我们的应用太复杂了,没法做单元测试。其实不一定是应用复杂,而有可能是设计得有问题,导致了没有可测试性。比如有些人喜欢在CXXXDialog里编写所有的功能实现,要测试这样的代码,必须得创建出Dialog,可能还需要点击,这显然没法做单元测试,但如果把Dialog和业务逻辑分开设计,那至少业务逻辑是可测试的(暂不讨论UI的测试)。因此要做单元测试,就得设计好各个接口,保证某个接口只完成单一的功能,没有过多的耦合依赖。

前面只是泛泛而谈了一些单元测试的皮毛,鼓吹了一些优点,有兴趣的自己找更详细的资料看吧。另推荐一个Google的开源C++测试框架googletest

posted @ 2011-09-15 06:37 RTY 阅读(325) | 评论 (0)编辑 收藏

     摘要: http://threadingbuildingblocks.org/事情十这样的,有同事想要统计某些广告的点击,在多线程下运行,可能会同时操作同一个数据项,最早使用一个全局锁,效果不好,现在改成了细粒度锁,每一个数据项一个锁,但还是希望性能更好些。我的想法是,使用Intel TBB的Atomic,这就避免了使用锁,同时性能也会提升,不过,到底能提升多少还要用数据说话。1. 不使用锁的情况#inc...  阅读全文

posted @ 2011-09-15 06:30 RTY 阅读(453) | 评论 (0)编辑 收藏

1. 读取ini、修改ini   使用ConfigParser
示例代码:
比如有一个文件Userinfo.ini,里面有这些内容:

[userinfo]
EngineVersion=0
DATVersion=5127
FileName=dat-5127.zip
FilePath=/pub/antivirus/datfiles/4.x/
FileSize=13481555
Checksum=6037,021E
MD5=aaeb519d3f276b810d46642d782d8921
那就可以通过下面这些代码得到MD5的值,简单吧
#!/usr/bin/env python
#
 -*- coding: utf-8 -*-

import ConfigParser

config 
= ConfigParser.ConfigParser()
config.readfp(open(
'update.ini'))

= config.get("ZIP","MD5")
print a

××××××××××××××××××××××××××××××××××××××××××××××××
写也很简单:
import ConfigParser

config 
= ConfigParser.ConfigParser()

# set a number of parameters
config.add_section("book")
config.set(
"book""title""the python standard library")
config.set(
"book""author""fredrik lundh")

config.add_section(
"ematter")
config.set(
"ematter""pages"250)

# write to file
config.write(open('1.ini'"w"))

×××××××××××××××××××××××××××××××××××××××××
修改也不难(添加内容):
#!/usr/bin/env python
#
 -*- coding: utf-8 -*-

import ConfigParser

config 
= ConfigParser.ConfigParser()

config.read(
'1.ini')

= config.add_section("md5")

config.set(
"md5""value""1234")

config.write(open(
'1.ini'"r+"))     #可以把r+改成其他方式,看看结果:)

修改内容:
#!/usr/bin/env python
#
 -*- coding: utf-8 -*-

import ConfigParser

config 
= ConfigParser.ConfigParser()

config.read(
'1.ini')

config.set(
"md5""value""kingsoft")    #这样md5就从1234变成kingsoft了

config.write(open(
'1.ini'"r+"))

posted @ 2011-09-02 21:57 RTY 阅读(331) | 评论 (0)编辑 收藏

仅列出标题
共31页: First 6 7 8 9 10 11 12 13 14 Last