Posted by & filed under Programming.

PHPUnit是一个轻量级的PHP测试框架。它是在PHP5下面对JUnit3系列版本的完整移植,是xUnit测试框架家族的一员(它们都基于模式先锋Kent Beck的设计)。单元测试是几个现代敏捷开发方法的基础,使得PHPUnit成为许多大型PHP项目的关键工具。这个工具也可以被Xdebug扩展用来生成代码覆盖率报告 ,并且可以与phing集成来自动测试,最后它还可以和Selenium整合来完成大型的自动化集成测试。

Windows平台LAMP环境XAMPP 1.7.3下如何安装PHPUnit呢?

首先,以管理员身份运行cmd,使用pear添加phpunit频道:

D:\xampp\php>pear channel-discover pear.phpunit.de
Channel “pear.phpunit.de” is already initialized

频道添加好,尝试安装PHPUnit:

D:\xampp\php>pear install phpunit/PHPUnit
Unknown remote channel: pear.symfony-project.com
Unknown remote channel: pear.symfony-project.com
Unknown remote channel: components.ez.no
Unknown remote channel: components.ez.no
phpunit/PHPUnit requires PEAR Installer (version >= 1.9.1), installed version is 1.9.0
phpunit/PHPUnit requires package “channel://pear.symfony-project.com/YAML” (version >= 1.0.2)
phpunit/PHPUnit can optionally use PHP extension “dbus”
phpunit/DbUnit requires PEAR Installer (version >= 1.9.1), installed version is1.9.0
phpunit/DbUnit requires package “channel://pear.symfony-project.com/YAML” (version >= 1.0.2)
phpunit/File_Iterator requires PEAR Installer (version >= 1.9.1), installed version is 1.9.0
phpunit/PHP_CodeCoverage requires PEAR Installer (version >= 1.9.1), installed version is 1.9.0
phpunit/PHP_CodeCoverage requires package “channel://components.ez.no/ConsoleTools” (version >= 1.6)
phpunit/PHP_CodeCoverage requires package “phpunit/File_Iterator” (version >= 1.2.2)
phpunit/PHP_CodeCoverage can optionally use PHP extension “xdebug” (version >= 2.0.5)
phpunit/PHPUnit_MockObject requires PEAR Installer (version >= 1.9.1), installed version is 1.9.0
phpunit/PHPUnit_Selenium requires PEAR Installer (version >= 1.9.1), installed version is 1.9.0
phpunit/PHP_TokenStream requires PEAR Installer (version >= 1.9.1), installed version is 1.9.0
phpunit/PHP_TokenStream requires package “channel://components.ez.no/ConsoleTools” (version >= 1.6)
No valid packages found
install failed

从提示看出,需要安装PEAR 1.9.1,而当前PEAR是1.9.0,那就要先升级PEAR版本。

pear list-upgrades可以列出当前可用的更新,
D:\xampp\php>pear.bat list-upgrades
WARNING: channel “pear.php.net” has updated its protocols, use “pear channel-update pear.php.net” to
update

D:\xampp\php>pear channel-update pear.php.net
Updating channel “pear.php.net”
Update of Channel “pear.php.net” succeeded

D:\xampp\php>pear.bat list-upgrades
PEAR.PHP.NET AVAILABLE UPGRADES (STABLE):
=========================================
CHANNEL PACKAGE LOCAL REMOTE SIZE
pear.php.net Archive_Tar 1.3.3 (stable) 1.3.7 (stable) 17.2kB
pear.php.net Console_Getargs 1.3.4 (stable) 1.3.5 (stable) 17.8kB
pear.php.net Mail 1.1.14 (stable) 1.2.0 (stable) 23kB
pear.php.net Mail_Mime 1.5.2 (stable) 1.8.1 (stable) 31kB
pear.php.net Mail_mimeDecode 1.5.1 (stable) 1.5.5 (stable) 11.4kB
pear.php.net Net_SMTP 1.3.4 (stable) 1.4.4 (stable) 12.1kB
pear.php.net Net_Socket 1.0.9 (stable) 1.0.10 (stable) 5.3kB
pear.php.net PEAR 1.9.0 (stable) 1.9.1 (stable) 287kB
pear.php.net Structures_Graph 1.0.3 (stable) 1.0.4 (stable) 30kB
Channel pear.phpunit.de: No upgrades available
ZEND.GOOGLECODE.COM/SVN AVAILABLE UPGRADES (STABLE):
====================================================
CHANNEL PACKAGE LOCAL REMOTE SIZE
zend.googlecode.com/svn zend 1.9.6 (stable) 1.11.1 (stable) -

更新所有可用更新:
D:\xampp\php>pear upgrade-all
Will upgrade channel://pear.php.net/archive_tar
Will upgrade channel://pear.php.net/console_getargs
Will upgrade channel://pear.php.net/mail
Will upgrade channel://pear.php.net/mail_mime
Will upgrade channel://pear.php.net/mail_mimedecode
Will upgrade channel://pear.php.net/net_smtp
Will upgrade channel://pear.php.net/net_socket
Will upgrade channel://pear.php.net/pear
Will upgrade channel://pear.php.net/structures_graph
Will upgrade channel://zend.googlecode.com/svn/zend
Did not download optional dependencies: pear/Auth_SASL, use –alldeps to download automatically
pear/Net_SMTP can optionally use package “pear/Auth_SASL”
downloading Archive_Tar-1.3.7.tgz …
Starting to download Archive_Tar-1.3.7.tgz (17,610 bytes)
……done: 17,610 bytes
downloading Console_Getargs-1.3.5.tgz …
Starting to download Console_Getargs-1.3.5.tgz (18,207 bytes)
…done: 18,207 bytes
downloading Mail-1.2.0.tgz …
Starting to download Mail-1.2.0.tgz (23,214 bytes)
…done: 23,214 bytes
downloading Mail_Mime-1.8.1.tgz …
Starting to download Mail_Mime-1.8.1.tgz (31,530 bytes)
…done: 31,530 bytes
downloading Mail_mimeDecode-1.5.5.tgz …
Starting to download Mail_mimeDecode-1.5.5.tgz (11,554 bytes)
…done: 11,554 bytes
downloading Net_SMTP-1.4.4.tgz …
Starting to download Net_SMTP-1.4.4.tgz (12,264 bytes)
…done: 12,264 bytes
downloading Net_Socket-1.0.10.tgz …
Starting to download Net_Socket-1.0.10.tgz (5,429 bytes)
…done: 5,429 bytes
downloading PEAR-1.9.1.tgz …
Starting to download PEAR-1.9.1.tgz (293,587 bytes)
…done: 293,587 bytes
downloading Structures_Graph-1.0.4.tgz …
Starting to download Structures_Graph-1.0.4.tgz (30,318 bytes)
…done: 30,318 bytes
downloading Zend-1.11.1.tgz …
Starting to download Zend-1.11.1.tgz (3,638,888 bytes)
…done: 3,638,888 bytes
upgrade-all ok: channel://pear.php.net/Archive_Tar-1.3.7
upgrade-all ok: channel://pear.php.net/Console_Getargs-1.3.5
upgrade-all ok: channel://pear.php.net/Mail-1.2.0
upgrade-all ok: channel://pear.php.net/Mail_Mime-1.8.1
upgrade-all ok: channel://pear.php.net/Net_Socket-1.0.10
upgrade-all ok: channel://pear.php.net/Structures_Graph-1.0.4
upgrade-all ok: channel://zend.googlecode.com/svn/Zend-1.11.1
upgrade-all ok: channel://pear.php.net/Mail_mimeDecode-1.5.5
upgrade-all ok: channel://pear.php.net/Net_SMTP-1.4.4
upgrade-all ok: channel://pear.php.net/PEAR-1.9.1
PEAR: Optional feature webinstaller available (PEAR’s web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR’s PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR’s PHP-GTK2-based installer)
PEAR: To install optional features use “pear install pear/PEAR#featurename”

更新成功后,PEAR已经是最新版了,
pear.symfony-project.com和components.ez.no两个频道也要添加一下:

D:\xampp\php>pear channel-discover pear.symfony-project.com
Adding Channel “pear.symfony-project.com” succeeded
Discovery of channel “pear.symfony-project.com” succeeded

D:\xampp\php>pear channel-discover components.ez.no
Adding Channel “components.ez.no” succeeded
Discovery of channel “components.ez.no” succeeded

再次尝试安装PHPUnit:

D:\xampp\php>pear install phpunit/PHPUnit
phpunit/PHPUnit can optionally use PHP extension “dbus”
phpunit/PHP_CodeCoverage can optionally use PHP extension “xdebug” (version >= 2.0.5)
downloading PHPUnit-3.5.5.tgz …
Starting to download PHPUnit-3.5.5.tgz (116,148 bytes)
………………..done: 116,148 bytes
downloading DbUnit-1.0.0.tgz …
Starting to download DbUnit-1.0.0.tgz (38,183 bytes)
…done: 38,183 bytes
downloading PHP_CodeCoverage-1.0.2.tgz …
Starting to download PHP_CodeCoverage-1.0.2.tgz (109,280 bytes)
…done: 109,280 bytes
downloading YAML-1.0.4.tgz …
Starting to download YAML-1.0.4.tgz (9,919 bytes)
…done: 9,919 bytes
downloading ConsoleTools-1.6.1.tgz …
Starting to download ConsoleTools-1.6.1.tgz (869,994 bytes)
…done: 869,994 bytes
downloading PHP_TokenStream-1.0.1.tgz …
Starting to download PHP_TokenStream-1.0.1.tgz (7,250 bytes)
…done: 7,250 bytes
downloading Base-1.8.tgz …
Starting to download Base-1.8.tgz (236,357 bytes)
…done: 236,357 bytes
install ok: channel://pear.symfony-project.com/YAML-1.0.4
install ok: channel://components.ez.no/Base-1.8
install ok: channel://pear.phpunit.de/DbUnit-1.0.0
install ok: channel://components.ez.no/ConsoleTools-1.6.1
install ok: channel://pear.phpunit.de/PHP_TokenStream-1.0.1
install ok: channel://pear.phpunit.de/PHP_CodeCoverage-1.0.2
install ok: channel://pear.phpunit.de/PHPUnit-3.5.5

PHPUnit安装成功!!!

Posted by & filed under Programming.

iimport sys
from PIL import Image, ImageFilter
 
def dropShadow( image, offset=(5,5), background=0xffffff,
        shadow=0x444444, border=8, iterations=3):
    """
    把图像放在一个作了高斯模糊的背景上
 
    image       - 要放在背景上的原始图像
    offset      - 阴影相对图像的偏移,用(x,y)表示,可以为正数或者负数
    background - 背景色
    shadow      - 阴影色
    border      - 图像边框,必须足够用来制作阴影模糊
    iterations - 过滤器处理次数,次数越多越模糊,当然处理过程也越慢
    """
 
    # 创建背景块
    totalWidth = image.size[0] + abs(offset[0]) + 2*border
    totalHeight = image.size[1] + abs(offset[1]) + 2*border
    back = Image.new(image.mode, (totalWidth, totalHeight), background)
 
    # 放置阴影块,考虑图像偏移
    shadowLeft = border + max(offset[0], 0)
    shadowTop = border + max(offset[1], 0)
    back.paste(shadow, [shadowLeft, shadowTop, shadowLeft + image.size[0],
        shadowTop + image.size[1]] )
 
    # 处理阴影的边缘模糊
    n = 0
    while n < iterations:
        back = back.filter(ImageFilter.BLUR)
        n += 1
 
    # 把图像粘贴到背景上
    imageLeft = border - min(offset[0], 0)
    imageTop = border - min(offset[1], 0)
    back.paste(image, (imageLeft, imageTop))
 
    return back
 
if __name__ == "__main__":
    pic="BCEB4D33FC86DC647461670FFC23D260.jpg"
    image = Image.open(pic)
    image.thumbnail( (300,300), Image.ANTIALIAS)
 
    dropShadow(image).show()
    dropShadow(image, background=0xeeeeee,
                  shadow=0x444444, offset=(0,5)).show()

生成前的原图:
生成前的原图
生成后的带阴影图:
生成后带阴影图

Posted by & filed under Programming.

首先上代码

# coding=utf-8
 
import os
import Image
 
# 字义缩放百分比
rate = 40
 
# 缩略图命名,在后面加上
resizedAddone = '_resized'
 
# 支持格式
suportFormat = ['bmp', 'gif', 'jpg', 'png']
 
def process(arg, dirs, files):
    for file in files:
        fileExt = os.path.splitext(file)[1].lower()[1:]
        if fileExt in suportFormat:
            img = Image.open(file)
            img.thumbnail((img.size[0] * rate / 100,
                                img.size[1] * rate / 100))
            img.save(os.path.basename(file)  \
                               + resizedAddone    \
                               + str(rate) + '.' + fileExt)
 
if __name__ == '__main__':
    os.path.walk('.', process, '123')

要运行此段代码需要安装PIL库,这是一个比较优秀的Python 图像处理库,使用的普及率类似PHP中的GD库,比较成熟和稳定,如果你需要更高的性能,image magick 是个相当不错的选择,image magick 的PHP扩展仍然有相当多的Bug,一般应用应该问题不大,至少在我的项目中应用还没出现过问题,我只是简单的应用到了缩略图的功能,仍然建议以命令行的形式调用,python 版本的还没试用过,从各方的使用反馈来看,似乎比PHP版本的口碑更好。

上面的代码是按照比例做缩略图,只需把源码放到你的图片目录下,然后运行就能批量生成缩略图了,如果你是需要固定尺寸的缩略图,只是需要 img.thumbnail()传递一个固定尺寸的tuple就好了,类似这样:img.thumbnail((120,100)),更多详细请查看PIL文档,不过这个文档相当的长,PDF版本有77页,非常的详细,当然也是因为PIL功能相当的完备和强大

Posted by & filed under Operating System.

配置是最低入门的512plan

4 CPUs in system; running 1 parallel copy of tests

Dhrystone 2 using register variables 12912633.7 lps (10.0 s, 7 samples)
Double-Precision Whetstone 2151.7 MWIPS (10.0 s, 7 samples)
Execl Throughput 892.6 lps (29.9 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 174974.5 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 46414.1 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 521010.8 KBps (30.0 s, 2 samples)
Pipe Throughput 249578.0 lps (10.0 s, 7 samples)
Pipe-based Context Switching 44742.9 lps (10.0 s, 7 samples)
Process Creation 1479.8 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 2334.2 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 673.1 lpm (60.1 s, 2 samples)
System Call Overhead 248224.2 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 12912633.7 1106.5
Double-Precision Whetstone 55.0 2151.7 391.2
Execl Throughput 43.0 892.6 207.6
File Copy 1024 bufsize 2000 maxblocks 3960.0 174974.5 441.9
File Copy 256 bufsize 500 maxblocks 1655.0 46414.1 280.4
File Copy 4096 bufsize 8000 maxblocks 5800.0 521010.8 898.3
Pipe Throughput 12440.0 249578.0 200.6
Pipe-based Context Switching 4000.0 44742.9 111.9
Process Creation 126.0 1479.8 117.4
Shell Scripts (1 concurrent) 42.4 2334.2 550.5
Shell Scripts (8 concurrent) 6.0 673.1 1121.8
System Call Overhead 15000.0 248224.2 165.5
========
System Benchmarks Index Score 343.5

————————————————————————
4 CPUs in system; running 4 parallel copies of tests

Dhrystone 2 using register variables 47311139.0 lps (10.0 s, 7 samples)
Double-Precision Whetstone 8496.2 MWIPS (9.8 s, 7 samples)
Execl Throughput 2652.3 lps (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 224996.5 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 60198.2 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 747652.1 KBps (30.0 s, 2 samples)
Pipe Throughput 948490.2 lps (10.0 s, 7 samples)
Pipe-based Context Switching 170475.4 lps (10.0 s, 7 samples)
Process Creation 4747.2 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 5697.3 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 746.2 lpm (60.1 s, 2 samples)
System Call Overhead 873882.0 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 47311139.0 4054.1
Double-Precision Whetstone 55.0 8496.2 1544.8
Execl Throughput 43.0 2652.3 616.8
File Copy 1024 bufsize 2000 maxblocks 3960.0 224996.5 568.2
File Copy 256 bufsize 500 maxblocks 1655.0 60198.2 363.7
File Copy 4096 bufsize 8000 maxblocks 5800.0 747652.1 1289.1
Pipe Throughput 12440.0 948490.2 762.5
Pipe-based Context Switching 4000.0 170475.4 426.2
Process Creation 126.0 4747.2 376.8
Shell Scripts (1 concurrent) 42.4 5697.3 1343.7
Shell Scripts (8 concurrent) 6.0 746.2 1243.6
System Call Overhead 15000.0 873882.0 582.6
========
System Benchmarks Index Score 839.6

单核测试性能也有300多分,这个表现相当出色,四核的测试能够超过839分也出乎意料,由于linode的高可用性和对亚洲的访问速度非常的快,虽然最低也要19美元,也算是物有所值

附上测试脚本:Unix bench

Posted by & filed under Operating System.

前些日子搞特惠,买了一个最低配置的,512M内存

VPS PACKAGE #1
VPS Software: vePortal™ / OpenVZ™
CPU: 1000MHZ GUARANTEED
Memory: 512MB GUARANTEED
Disk Space: 20GB (RAID BASED CONFIG)
Bandwidth: 1000GB/MONTH
IP Addresses: 2 (IPv4) + IPv6
Management: BASIC MANAGED
DDOS Protection: CISCO™ GUARD
FREE SETUP $5.95/MONTH

================================================================
BYTE UNIX Benchmarks (Version 5.1.3)

System: 200689.www.foxapp.com: GNU/Linux
OS: GNU/Linux — 2.6.18-194.26.1.el5.028stab070.14 — #1 SMP Thu Nov 18 16:34 :01 MSK 2010
Machine: x86_64 (x86_64)
Language: en_US.utf8 (charmap=”UTF-8″, collate=”UTF-8″)
CPU 0: Intel(R) Xeon(R) CPU E5620 @ 2.40GHz (4788.1 bogomips)
Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET, Intel virtualization
05:07:23 up 6 min, 1 user, load average: 0.08, 0.02, 0.01; runlevel 3

————————————————————————
Benchmark Run: Fri Jan 28 2011 05:07:23 – 05:37:17
1 CPU in system; running 1 parallel copy of tests

Dhrystone 2 using register variables 12759700.9 lps (10.0 s, 7 samples)
Double-Precision Whetstone 2797.2 MWIPS (10.0 s, 7 samples)
Execl Throughput 3383.2 lps (29.6 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks 506737.3 KBps (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks 142917.2 KBps (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks 1087584.1 KBps (30.0 s, 2 samples)
Pipe Throughput 948149.4 lps (10.0 s, 7 samples)
Pipe-based Context Switching 277958.2 lps (10.0 s, 7 samples)
Process Creation 10813.4 lps (30.0 s, 2 samples)
Shell Scripts (1 concurrent) 4151.6 lpm (60.0 s, 2 samples)
Shell Scripts (8 concurrent) 583.2 lpm (60.1 s, 2 samples)
System Call Overhead 862516.8 lps (10.0 s, 7 samples)

System Benchmarks Index Values BASELINE RESULT INDEX
Dhrystone 2 using register variables 116700.0 12759700.9 1093.4
Double-Precision Whetstone 55.0 2797.2 508.6
Execl Throughput 43.0 3383.2 786.8
File Copy 1024 bufsize 2000 maxblocks 3960.0 506737.3 1279.6
File Copy 256 bufsize 500 maxblocks 1655.0 142917.2 863.5
File Copy 4096 bufsize 8000 maxblocks 5800.0 1087584.1 1875.1
Pipe Throughput 12440.0 948149.4 762.2
Pipe-based Context Switching 4000.0 277958.2 694.9
Process Creation 126.0 10813.4 858.2
Shell Scripts (1 concurrent) 42.4 4151.6 979.2
Shell Scripts (8 concurrent) 6.0 583.2 972.0
System Call Overhead 15000.0 862516.8 575.0
========
System Benchmarks Index Score 883.3

883.3的评分相当彪悍,相对于其价格来说,相当不错了,Burst有个很大的Bug是他的统计流量的系统,那玩意一点也不靠谱,我发过ticket给他们,回复说是已知的Bug,目前不限制流量,也就是显示多少无所谓了。

Posted by & filed under Programming.

Httpsqs 是张宴基于Tokyo Cabinet做的一个队列服务
前些日子项目中需要一个队列服务,因为配合Gearman做分发服务,因为之前的一些经历和教训,没有采用PHP作为脚本语言,当然并不是说PHP不行,只是懒得去折腾一些莫名其妙的问题,转而采用在更稳定更省心的Python做开发,之前其他的项目组中有使用Httpsqs的经历,我的leader强烈建议我使用这个,其实我更倾向memcacheQ 或者redis,Httpsqs没有Python版本的client,顺手写了一个,地址如下:
http://code.google.com/p/httpsqs/source/browse/#svn%2Ftrunk%2Fclient%2Fpython

这个玩意是能正常的跑在我的项目中,不能保证能完全满足你的需求,如果你有任何建议或者意见,也欢迎联系我,特别附加一句:本人对此代码所带来的一切悲剧或者喜剧不承担任何责任,请慎重使用!

贴一段关于httpsqs的介绍,怕有些人不知道,知道的请忽略。

TTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key/Value 数据库来做数据的持久化存储。

  项目网址:http://code.google.com/p/httpsqs/
  使用文档:http://blog.s135.com/httpsqs/
  使用环境:Linux(同时支持32位、64位操作系统,推荐使用64位操作系统)
  软件作者:张宴

  队列(Queue)又称先进先出表(First In First Out),即先进入队列的元素,先从队列中取出。加入元素的一头叫“队头”,取出元素的一头叫“队尾”。利用消息队列可以很好地异步处理数据传送和存储,当你频繁地向数据库中插入数据、频繁地向搜索引擎提交数据,就可采取消息队列来异步插入。另外,还可以将较慢的处理逻辑、有并发数量限制的处理逻辑,通过消息队列放在后台处理,例如FLV视频转换、发送手机短信、发送电子邮件等。

  HTTPSQS 具有以下特征:

  ● 非常简单,基于 HTTP GET/POST 协议。PHP、Java、Perl、Shell、Python、Ruby等支持HTTP协议的编程语言均可调用。
  ● 非常快速,入队列、出队列速度超过10000次/秒。
  ● 高并发,支持上万的并发连接,C10K不成问题。
  ● 支持多队列。
  ● 单个队列支持的最大队列数量高达10亿条。
  ● 低内存消耗,海量数据存储,存储几十GB的数据只需不到100MB的物理内存缓冲区。
  ● 可以在不停止服务的情况下便捷地修改单个队列的最大队列数量。
  ● 可以实时查看队列状态(入队列位置、出队列位置、未读队列数量、最大队列数量)。
  ● 可以查看指定队列ID(队列点)的内容,包括未出、已出的队列内容。
  ● 查看队列内容时,支持多字符集编码。
  ● 源代码不超过800行,适合二次开发。

Posted by & filed under Programming.

废话不多说,先上代码:

#encoding=utf-8
import threading
import random
import time
from Queue import Queue
import mutex
 
class Producer(threading.Thread):
 
    def __init__(self, threadname, queue, lock):
        threading.Thread.__init__(self, name = threadname)
        self.sharedata = queue
        self.lock = lock
 
    def run(self):
        for i in range(20):
            #----------------
            self.lock.acquire()
            print self.getName(),'<< ',i
            self.lock.release()
            #----------------
            self.sharedata.put(i)
            time.sleep(random.randrange(10)/50.0)
            #time.sleep(1)
        print self.getName(),'Finished'
 
 
# Consumer thread
 
class Consumer(threading.Thread):
 
 
    global lock
    def __init__(self, threadname, queue, lock):
        threading.Thread.__init__(self, name = threadname)
        self.sharedata = queue
        self.lock = lock
 
 
    def run(self):
        for i in range(20):
            #----------------
            self.lock.acquire()
            print self.getName(),'        >> ',self.sharedata.get()
            self.lock.release()
            #----------------
            time.sleep(random.randrange(10)/50.0)
            #time.sleep(1)
        print self.getName(),'Finished'
 
 
# Main thread
 
def main():
 
    lock = threading.RLock()
    queue = Queue()
    producer = Producer('Producer', queue, lock)
    consumer = Consumer('Consumer', queue, lock)
    print 'Starting threads ...'
    producer.start()
    consumer.start()
    producer.join()
    consumer.join()
    print 'All threads have terminated.'
 
if __name__ == '__main__':
    main()

这个是在学习多线程的时候入门经典实例之一,这里只是加了个同步锁(RLock)
多次执行这个脚本会发现,大部分时候这个脚本会发生死锁的现象,偶尔却能正确的执行完

这个问题并不是锁本身的问题,是程序的逻辑问题

producer和 consumer 都sleep 如下时间

time.sleep(random.randrange(10)/50.0)

当consumer sleep时间小于producer 的时候而队列为空的时候就会发生貌似死锁的现象

之所以说是貌似,是因为这个并不是死锁引起的问题,而是queue 的get方法,这个方法有个timeout的可选参数,如果没有这个参数,那么get会一直等待队列中添加新的元素进来才会返回,所以后面的consumer 的 release并没有执行导致队列一直锁在那里,producer也没法写入,

关于queue get方法的更详细用法请参阅python手册Queue章节

Python 的 queue 实现就是线程安全的,没有必要上锁,这里就是因为 queue 内部的锁机制同你的锁冲突了,如果要是想自己控制的话,那么 queue 的 put 和 get 都得用 nowait 的方法

Posted by & filed under Life Diary.

感觉2009年总结才刚刚写,怎么又写2010年总结了呢,如果不是在Google Reader中看到那么多牛人都发布了自己的总结,差点忘记了已经又过了一年。
回首过去的一年,对于国家只有一个字:“涨”,房价涨,菜价涨,食用油涨价,电费涨价,连厕纸都涨了20%以上,楼下的包子以前一块钱两个小的,现在一块钱只能买一个喽,公司食堂最贵的菜从8块跳到了10块,还好,工资没涨!
对于自己,也只能用一个字形容:“忙”,非常忙,特别忙,忙得昏天暗地,不停的加班、加班、加班、加班……去年元旦前后进入状态后,一直就是不停的做着各种各样项目。
关于生活
过去的一年不欢不喜,老人说这就是生活,我租了一套在资产泡沫的朦胧的光辉下价值两百万人民币的公寓。在杭州这样的高空置率的城市里,最大的好处就是房租相对还算可以接受,虽然房价虚高。给房子里填齐了各种各样的锅碗瓢盆,明年老娘来的时候就不用被说空着那么大的厨房,没地方做饭了,想想日子倒是也过得衣食无忧,连感冒都没有过,不过没存下来什么钱。又长一岁,开始更关注,房子、车子、票子、妻子、老子……
关于工作:
前面说过这一年主旋律是就一个“忙”字,不过也算是看了不少的书,甚至不少好书,也实践了不少想法,甚至又重新尝试搞起了垃圾站,实践证明现在的搜索引擎已经不是四年前的搜索引擎,实在没那么好欺骗,自然我的小九九就落空了。在我的2009年总结中,我提到2010年要好好学习两门语言,一个英语一个 Python,英语没怎么学,除了多认识了几个单词之外,无所长进,Python倒是学习并应用了一段时间,写了一个google app engine 应用,写了一个简单的CMS系统,写一个爬虫,写了个静态文件的压缩与简单分词,爬虫每天可以抓取和处理四千万左右个页面,压缩与去重处理大概能处理几十G数据,看了好些关于这方面的论文,也算是一种收获吧,虽然都是实践性项目。关于我所每天从事的工作,一个考虑公司可能不让说,另外一个考虑也没啥好说的,社区电子商务这个模式跟我曾经对某位在搞互联网电视的朋友说的一样:没人踏足的领域不一定就是块风水宝地,做成功了,我们就是英雄,做不成功就是英烈,当然成为英烈的可能性更大一些。年末进入的移动互联网倒是有奔头,但目前这个领域也仅仅是看好,并没有成熟的用户群,一群公司蜂拥而上就跟当年美国和苏联抢着登月球一样。我咋这么悲观呢……
关于机遇:
2010年是中国经济全面从复苏走向泡沫的一年,各种资本变着法进入各种领域深藏起来,从年初的民工荒,到后来的技术荒,团购网站铺天盖地,优酷、当当等乘着机会到海外圈钱,创业版的开市又为中国无辜的P民提供了一个合法的赌场,过去一年中国股市新发股票价值超过万亿,而市值却没有任何提升,蒸发了万亿。好友离开公司去了北京,本也想换个环境,最后为了几斗米而折腰,人家说会有期权和股权,我觉得那些都是骗人的,结果就在这个月(2011年1月)这丫居然真的在纳斯达克上市了,悲哉!2010年过得是这辈子到目前为止最忙的一年,也是最有想法的一年,或许慢慢的进入了这个圈子,或者是迫于压力,总是试着去做一些尝试,虽无所收获,也算是一种锻炼和对自己的历练。
关于2011年:
不管明年是不是2012,努力还是要努力的。去年没有完成的今年肯定要完成,比如英语,阅读已经不是什么问题,问题出在口语上,实在不行,出点血吧,去新东方搞一下,这玩意没环境确实不好学。Python暂时搁置一下,准备搞一下C和搜索算法这一块的东西,或许能为移动终端贡献一点东西

Posted by & filed under Excellence Article, Programming.

Python具有强大的扩展能力,网上有人列出了50个很棒的Python模块,包含几乎所有的需要:比如Databases,GUIs,Images, Sound, OS interaction, Web,以及其他。推荐收藏。

Graphical interface wxPython http://wxpython.org
Graphical interface pyGtk http://www.pygtk.org
Graphical interface pyQT http://www.riverbankcomputing.co.uk/pyqt/
Graphical interface Pmw http://pmw.sourceforge.net/
Graphical interface Tkinter 3000 http://effbot.org/zone/wck.htm
Graphical interface Tix http://tix.sourceforge.net/

Database MySQLdb http://sourceforge.net/projects/mysql-python
Database PyGreSQL http://www.pygresql.org/
Database Gadfly http://gadfly.sourceforge.net/
Database SQLAlchemy http://www.sqlalchemy.org/
Database psycopg http://www.initd.org/pub/software/psycopg/
Database kinterbasdb http://kinterbasdb.sourceforge.net/
Database cx_Oracle http://www.cxtools.net/default.aspx?nav=downloads
Database pySQLite http://initd.org/tracker/pysqlite

MSN Messenger msnlib http://auriga.wearlab.de/~alb/msnlib/
MSN Messenger pymsn http://telepathy.freedesktop.org/wiki/Pymsn
MSN Messenger msnp http://msnp.sourceforge.net/
Network Twisted http://twistedmatrix.com/
Images PIL http://www.pythonware.com/products/pil/
Images gdmodule http://newcenturycomputers.net/projects/gdmodule.html
Images VideoCapture http://videocapture.sourceforge.net/

Sciences and Maths scipy http://www.scipy.org/
Sciences and Maths NumPy http://numpy.scipy.org//
Sciences and Maths numarray http://www.stsci.edu/resources/software_hardware/numarray
Sciences and Maths matplotlib http://matplotlib.sourceforge.net/

Games Pygame http://www.pygame.org/news.html
Games Pyglet http://www.pyglet.org/
Games PySoy http://www.pysoy.org/
Games pyOpenGL http://pyopengl.sourceforge.net/
Jabber jabberpy http://jabberpy.sourceforge.net/
Web scrape http://zesty.ca/python/scrape.html
Web Beautiful Soup http://crummy.com/software/BeautifulSoup
Web pythonweb http://www.pythonweb.org/
Web mechanize http://wwwsearch.sourceforge.net/mechanize/

Localisation geoname.py http://www.zindep.com/blog-zindep/Geoname-python/

Serial port pySerial http://pyserial.sourceforge.net/
Serial port USPP http://ibarona.googlepages.com/uspp

Parallel Port pyParallel http://pyserial.sourceforge.net/pyparallel.html

USB Port pyUSB http://bleyer.org/pyusb/

Windows ctypes http://starship.python.net/crew/theller/ctypes/
Windows pywin32 http://sourceforge.net/projects/pywin32/
Windows pywinauto http://www.openqa.org/pywinauto/
Windows pyrtf http://pyrtf.sourceforge.net/
Windows wmi http://timgolden.me.uk/python/wmi.html

PDA/GSM/Mobiles pymo http://www.awaretek.com/pymo.html
PDA/GSM/Mobiles pyS60 http://sourceforge.net/projects/pys60

Sound pySoundic http://pysonic.sourceforge.net/
Sound pyMedia http://pymedia.org/
Sound FMOD http://www.fmod.org/
Sound pyMIDI http://www.cs.unc.edu/Research/assist/developer.shtml

GMail libgmail http://libgmail.sourceforge.net/
Google pyGoogle http://pygoogle.sourceforge.net/
Expect pyExpect http://pexpect.sourceforge.net/
WordNet pyWordNet http://osteele.com/projects/pywordnet/
Command line cmd http://blog.doughellmann.com/2008/05/pymotw-cmd.html
Compiler backend llvm-py http://mdevan.nfshost.com/llvm-py/
3D VPython http://vpython.org

Posted by & filed under Life Diary.

  1. Q:如何保证产品可用性?
    A:先做出来吧,能用就行,不能用再改嘛,不行就加机器
  2. Q:如何保证产品的性能?
    A:狗屁性能,现在人都没有还要啥性能,先照简单的做,把功能实现了先,以后的事情以后再说
  3. Q:如何保证产品的可维护性?
    A:维护啥啊,还有一堆功能要实现呢!刚开完会,前面做的那些东西又要整,再说这个项目已经做成这样了,现在没时间回头整理东西,需求要得急啊,这个东西应该一开始就做啊,现在代价太大了,下个项目再说吧
  4. Q:如何进行产品测试?
    A:这个真没想过,让测试去做计划吧,尽量做好自测吧,用户急着要这个功能,先赶工吧

以上是我经常听到的回答,至于对与错,屁股决定脑袋