2008-04-23

热烈祝贺访问量首次突破50

虽然我的blog的初衷只是为了整理自己的笔记方面日后查找,并不是为了给别人看,但是看到能帮助别人也确实感到很高兴。

根据Google Analytics的数据,2008.04.22日访问量为57,创历史新高,且首次突破50。 主要原因还是最近Blogspot解封了,要不我就得庆祝突破20了。

python urllib.urlopen 使用代理的方法

urllib.urlopen(url, proxies={'http' : 'http://address:port'})

2008-04-22

游戏推荐: The Python Challenge

http://www.pythonchallenge.com/

这是一个猜url闯关的在线游戏,主要利用的python语言的各种知识。十分有趣。

Thunderbird 插件 Provider for Google Calendar 报 "Requires addtional items" 错误的解决

原来的lightning是在源里装的,版本号为0.7, 更新至最新版0.8后问题消失。

有关 64位Linux 驱动 Atheros 5007EG 无线网卡

[2008-10-03 更新]ubuntu 8.10中新增了acer_wmi模块,可以完美驱动无线网卡了 :)

系统是 Ubuntu 8.04 rc amd64,笔记本是Acer Aspire 4520

无线网卡现在看来是 Atheros 5007EG, 为什么这么说呢,我主要依靠lspci判断,最早识别不出来,后来能认出Atheros,但是没型号。然后一段时间内都认成5006EG。当时也是按它装的驱动。但是最近update pciid后又认成了AR242x。 在http://madwifi.org/wiki/Compatibility/Atheros 上是这么说的

Atheros AR5007EG

Chipset:AR2425 / AR5007EG
URL:http://atheros.com/pt/AR5007EG.htm
Supports:802.11b 802.11g
Interface:PCI-Express x1
Device Information: Ethernet controller: Atheros Communications, Inc. Unknown device 001c (rev 01),Subsystem: AMBIT Microsystem Corp. Unknown device 3065
Notes:not supported by HAL as of 2007.04.28 - resturns Hal status 13
Notes:Suported by ndiswrapper with windows driver, but some user reports crash problems
Notes:Instructions about how to use the windows driver + ndiswrapper
Notes:works fine with ndiswrapper, using old drivers, search ubuntu forums
Notes:Sometimes erroneously reported as an AR5006EG by lspci
Notes:Works perfectly with latest madwifi snapshot and this patch --> http://madwifi.org/ticket/1679
Notes:This patch is tested and working on:
Notes:Acer Aspire 5315, Acer Aspire 5520 - detected as AR5006EG, Acer Aspire 5613WLMi, Acer Aspire 5720Z, Toshiba Satellite A210, LG E500, Packard Bell EasyNote? MX-52, Samsung P500, Asus X51RL, MSI-VR601-051, Fujitsu-Siemens Amilo LI1718, Fujitsu-Siemens Amilo PA2510, Asus EEEPC more, Acer Aspire 5570, Acer Aspire 5100, Toshiba Satellite Pro L40-136, Toshiba Satellite P200-170 (PSPBQA) - detected as AR5006EG, Acer Aspire 5050-3785 - detect as AR5006eg working ok
Notes:How-to compile madwifi and the patch
Notes:Works on HP dv6730eg, openSuse 10.3 after installing http://www.pc-forum24.de/suse-treiber/7830-experimentelle-madwifi-pakete-fuer-karten-mit-ar2425-ar5007eg-chipsatz-nur-32-bit.html and kdenetworkmanager
Notes:Does not work with HP dv9722eg (64Bit), no results with ndiswrapper, svn and snapshots with patches, sometimes HAL status 13 and sometimes HAL status 3

于是现在看来,觉得这个就是我的情况。

之前用32位的时候无线网卡一开始也搞了很长时间。 主要是最初查到Atheros有linux下的驱动madwifi。然后试了半天也不行,结果在官网上查到了当时不支持。于是只好用ndiswrapper配windows xp的驱动,工作的也不错。

现在升了64位, ndiswrapper不能挂32位的驱动了,winxp64位的驱动又特别难找。 (倒是有vista64的驱动,但是ndiswrapper不支持)。 于是又想到了madwifi. 也看到了上面的文字。 不过它的5007的snapshot只支持32位,比较郁闷。 一开始我还不知道, co了svn上的代码编译安装,编译是有个小问题,手工解决,然后倒是能载入,但是不能支持网卡。 于是只好又回到ndiswrapper.

那么就要找winxp64的驱动了,仔细找找也找到了不少,ndiswrapper也能安装这些驱动,但是挂载ndiswrapper内核模块后仍没网卡,dmesg说ACPI的IRQ7的问题。 一时又没了主意。

偶然进到了ndiswrapper支持网卡列表http://ndiswrapper.sourceforge.net/joomla/index.php?/component/option,com_openwiki/Itemid,33/id,list_a/(后来后悔:一开始怎么没想到进去看看呢)发现了很多类似网卡,尤其很多标以pci id: 168c:001c正好和我的一样。 其中有三个这样的,里面有两个给出了64位的winxp驱动的地址。而这两个只有一个是免费的,如下:

Laptop: Acer Aspire 5570Z根据最后一个链接下到了一个通用驱动,找到winxp64的驱动用ndiswrapper安装。但是载入内核模块后仍是同样的错误。仔细看上面说明是要求卸载madwifi驱动,我一一rmmod后重载ndiswrapper也无效。于是干脆重启,心想不成功便成仁。 不行就跟Wireless告别一段时间。 没想到重启后再一试竟然好了,实在是高兴。 这也说明当时我搜到的其他winxp64驱动也应该奏效。

不管怎样,经过一个晚上的努力,终于把无线网卡弄好了,值得庆贺。

初尝 Ubuntu 64

最近Ubuntu 8.04 rc刚出, 我脑袋一热装了个amd64版本的。

之前也想过是否要装个64位的,但是经过多方调查,当时64位无论是系统上还是软件上都不成熟。 比如没有flash插件和w32codecs, 不过现在不同了。 flash直接装nonfree的那个就行了, codec有w64codecs。 只是我的无线网卡配了好久。

总的来说性能有明显提升。注意是明显,不是很大。 而且我尽量排除了心里因素。 一个主要的改善是图形界面的响应整体加快了。

在64位的大形势下, 软硬件愈发成熟。 感觉真是不错。

2008-04-20

Transmission: 轻量级BT客户端

轻量级有时隐含着功能少,所以通常我宁可用重量级的。

但是今天偶然试了一下Transmission, 然后就把Azureus卸了。当然Azureus也很不错,以前一直用它,只是我也用不了什么高级功能,眼不见心不烦。况且下的东西也是很热门的(ubuntu的cd),基本不需要客户端费劲心思找peer。

Transmission很简介,效率也不错。值得一用。

2008-04-18

手工更改firefox语言环境

最近想在英文Windows下使用日文Firefox,下了语言包后还是英文的。Windows下似乎不能像Linux那样先设个LC_ALL再启动。

于是想到了about:config, 搜索 locale, 最后发现修改general.useragent.locale即可

ubuntu 下编译安装 compiz 插件所需的包

参考:http://forum.ubuntu.org.cn/viewtopic.php?t=89199&postdays=0&postorder=asc&start=0&sid=96eee591eddbfae76538f6c47b5add88

sudo apt-get install compiz-bcop compiz-dev build-essential libxcomposite-dev libpng12-dev libsm-dev libxrandr-dev libxdamage-dev libxinerama-dev libstartup-notification0-dev libgconf2-dev libgl1-mesa-dev libglu1-mesa-dev libmetacity-dev librsvg2-dev libdbus-1-dev libdbus-glib-1-dev libgnome-desktop-dev libgnome-window-settings-dev gitweb curl autoconf automake automake1.9 libtool intltool libxslt1-dev xsltproc emerald x11proto-scrnsaver-dev libxss-dev

Pidgin 的 Now Playing 插件使用方法

Pidgin 有个 Now Playing 插件看似不错,关键是支持我常用的BMPx,但是刚装上发现不会用

在http://m0n5t3r.info/work/pidgin-mpris上查到了,原来应该在自定义消息中加入%now-playing字符串,之后它便会被替换。

2008-04-15

再说修改ubuntu默认字体


ubuntu 中文默认字体的设置我曾提到修改/etc/fonts/conf.d/65-nonlatin.conf,但是今天还了语言后发现不好使了,man了一下fonts-conf发现原来的做法并不优美

更好的办法是修改/etc/fonts/conf.d/69-language-selector-*.conf,其中*会根据你的locale而改变。修改方式同前。


2008-04-06

Gnome下的键盘设置的小技巧

今天突然发现Keyboard设置里面有个Model选项,于是试着设成的Acer Laptop,因为我用的Acer笔记本。
然后发现那些快速启动键都能很好的识别了,具体表现是设置快捷键是可以显示出有意义的字符了,如XF86AudioPlay
不错不错

[转]让CPU占用率曲线听你指挥

题目《让CPU占用率曲线听你指挥》

问题

写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:

1. CPU的占用率固定在50%,为一条直线;
2. CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1~ 100);
3. CPU的占用率状态是一个正弦曲线。

分析与解法

有一名学生写了如下的代码:

while (true)
{
if (busy)
i++;
else

}


然后她就陷入了苦苦思索:else干什么呢?怎么才能让电脑不做事情呢?CPU使用率为0的时候,到底是什么东西在用CPU?另一名学生花了很多时间构想如何“深入内核,以控制CPU占用率”——可是事情真的有这么复杂么?
MSRA TTG(Microsoft Research Asia, Technology Transfer Group)的一些实习生写了各种解法,他们写的简单程序可以达到如图1-1所示的效果。

498)this.style.width=498;" onmousewheel="javascript:return big(this)" alt="" src="http://new.51cto.com/files/uploadimg/20080306/103426364.jpg" border="0" height="367" width="324">
图1-1 编码控制CPU占用率呈现正弦曲线形态

看 来这并不是不可能完成的任务。让我们仔细地回想一下写程序时曾经碰到的问题,如果我们不小心写了一个死循环,CPU占用率就会跳到最高,并且一直保持 100%。我们也可以打开任务管理器 ,实际观测一下它是怎样变动的。凭肉眼观察,它大约是1秒钟更新一次。一般情况下,CPU使用率会很低。但是,当用户运行一个程序,执行一些复杂操作的时 候,CPU的使用率会急剧升高。当用户晃动鼠标时,CPU的使用率也有小幅度的变化。

那当任务管理器报告CPU使用率为0的时候,谁在使用CPU呢?通过任务管理器的“进程(Process)”一栏可以看到,System Idle Process占用了CPU空闲的时间——这时候大家该回忆起在“操作系统原理”这门课上学到的一些知识了吧。系统中有那么多进程,它们什么时候能“闲下 来”呢?答案很简单,这些程序或者在等待用户的输入,或者在等待某些事件的发生(WaitForSingleObject()),或者进入休眠状态(通过 Sleep()来实现)。

在任务管理器的一个刷新周期内,CPU忙(执行应用程序)的时间和刷新周期总时间的比率,就是CPU的占用率,也就是说,任务管理器中显示的是每个 刷新周期内CPU占用率的统计平均值。因此,我们写一个程序,让它在任务管理器的刷新期间内一会儿忙,一会儿闲,然后通过调节忙/闲的比例,就可以控制任 务管理器中显示的CPU占用率。

【解法一】简单的解法

步骤1 要操纵CPU的usage曲线,就需要使CPU在一段时间内(根据Task Manager的采样率)跑busy和idle两个不同的loop,从而通过不同的时间 比例,来获得调节CPU Usage的效果。

步骤2 Busy loop可以通过执行空循环来实现,idle可以通过Sleep()来实现。

问题的关键在于如何控制两个loop的时间,方法有二:

Sleep一段时间,然后以for循环n次,估算n的值。

那么对于一个空循环for(i = 0; i <>

loop:
mov dx i ;将i置入dx寄存器
inc dx ;将dx寄存器加1
mov i dx ;将dx中的值赋回i
cmp i n ;比较i和n
jl loop ;i小于n时则重复循环

假设这段代码要运行的CPU是P4 2.4Ghz(2.4 * 10的9次方个时钟周期每秒)。现代CPU每个时钟周期可以执行两条以上的代码,那么我们就取平均值两条,于是让(2 400 000 000 * 2)/5=960 000 000(循环/秒),也就是说CPU 1秒钟可以运行这个空循环960 000 000次。不过我们还是不能简单地将n = 60 000 000,然后Sleep(1000)了事。如果我们让CPU工作1秒钟,然后休息1秒钟,波形很有可能就是锯齿状的——先达到一个峰值(大 于>50%),然后跌到一个很低的占用率。

我们尝试着降低两个数量级,令n = 9 600 000,而睡眠时间相应改为10毫秒(Sleep(10))。用10毫秒是因为它不大也不小,比较接近Windows的调度时间片。如果选得太小(比如1 毫秒),则会造成线程频繁地被唤醒和挂起,无形中又增加了内核时间的不确定性影响。最后我们可以得到如下代码:

代码清单1-1

 

int main()
{
for(;;)
{
for(int i = 0; i < 9600000; i++);
Sleep(10);
}
return 0;
}

在不断调整9 600 000的参数后,我们就可以在一台指定的机器上获得一条大致稳定的50% CPU占用率直线。
使用这种方法要注意两点影响:

1. 尽量减少sleep/awake的频率,如果频繁发生,影响则会很大,因为此时优先级更高的操作系统内核调度程序会占用很多CPU运算时间。
2. 尽量不要调用system call(比如I/O这些privilege instruction),因为它也会导致很多不可控的内核运行时间。
该方法的缺点也很明显:不能适应机器差异性。一旦换了一个CPU,我们又得重新估算n值。有没有办法动态地了解CPU的运算能力,然后自动调节忙/闲的时间比呢?请看下一个解法。

【解法二】使用GetTickCount()和Sleep()
我们知道GetTickCount()可以得到“系统启动到现在”的毫秒值,最多能够统计到49.7天。另外,利用Sleep()函数,最多也只能精确到1毫秒。因此,可以在“毫秒”这个量级做操作和比较。具体如下:

利用GetTickCount()来实现busy loop的循环,用Sleep()实现idle loop。伪代码如下:

代码清单1-2

 int busyTime = 10;  //10 ms
int idleTime = busyTime; //same ratio will lead to 50% cpu usage

Int64 startTime = 0;
while (true)
{
startTime = GetTickCount();
// busy loop的循环
while ((GetTickCount() - startTime) <= busyTime) ;

//idle loop
Sleep(idleTime);
}


这两种解法都是假设目前系统上只有当前程序在运行,但实际上,操作系统中有很多程序都会在不同时间执行各种各样的任务,如果此刻其他进程使用了10% 的CPU,那我们的程序应该只能使用40%的CPU(而不是机械地占用50%),这样可达到50%的效果。

怎么做呢?
我们得知道“当前CPU占用率是多少”,这就要用到另一个工具来帮忙——Perfmon.exe。

Perfmon是从Windows NT开始就包含在Windows服务器和台式机操作系统的管理工具组中的专业监视工具之一(如图1-2所示)。Perfmon可监视各类系统计数器,获取 有关操作系统、应用程序和硬件的统计数字。Perfmon的用法相当直接,只要选择您所要监视的对象(比如:处理器、RAM或硬盘),然后选择所要监视的 计数器(比如监视物理磁盘对象时的平均队列长度)即可。还可以选择所要监视的实例,比如面对一台多CPU服务器时,可以选择监视特定的处理器。

498)this.style.width=498;" onmousewheel="javascript:return big(this)" alt="" src="http://new.51cto.com/files/uploadimg/20080306/103439305.jpg" border="0" height="284" width="347">
图1-2 系统监视器(Perfmon)

我们可以写程序来查询Perfmon的值,Microsoft .Net Framework提供了PerformanceCounter()这一类型,从而可以方便地拿到当前各种计算机性能数据,包括CPU的使用率。例如下面这个程序——

【解法三】能动态适应的解法
代码清单1-3

//C# code
static void MakeUsage(float level)
{
PerformanceCounter p = new PerformanceCounter("Processor", "% Processor Time", "_Total");

while (true)
{
if (p.NextValue() > level)
System.Threading.Thread.Sleep(10);
}
}


可以看到,上面的解法能方便地处理各种CPU使用率参数。这个程序可以解答前面提到的问题2。
有了前面的积累,我们应该可以让任务管理器画出优美的正弦曲线了,见下面的代码。

【解法四】正弦曲线
代码清单1-4

 //C++ code  to make task manager generate sine graph
#include "Windows.h"
#include "stdlib.h"
#include "math.h"

const double SPLIT = 0.01;
const int COUNT = 200;
const double PI = 3.14159265;
const int INTERVAL = 300;

int _tmain(int argc, _TCHAR* argv[])
{
DWORD busySpan[COUNT]; //array of busy times
DWORD idleSpan[COUNT]; //array of idle times
int half = INTERVAL / 2;
double radian = 0.0;
for(int i = 0; i < COUNT; i++)
{
busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));
idleSpan[i] = INTERVAL - busySpan[i];
radian += SPLIT;
}

DWORD startTime = 0;
int j = 0;
while (true)
{
j = j % COUNT;
startTime = GetTickCount();
while ((GetTickCount() - startTime) <= busySpan[j]) ;
Sleep(idleSpan[j]);
j++;
}
return 0;
}

讨论
如果机器是多CPU,上面的程序会出现什么结果?如何在多个CPU时显示同样的状态?例如,在双核的机器上,如果让一个单线程的程序死循环,能让两个CPU的使用率达到50%的水平么?为什么?

多CPU的问题首先需要获得系统的CPU信息。可以使用GetProcessorInfo()获得多处理器的信息,然后指定进程在哪一个处理器上运行。其中指定运行使用的是SetThreadAffinityMask()函数。

另外,还可以使用RDTSC指令获取当前CPU核心运行周期数。

在x86平台上定义函数:

inline __int64 GetCPUTickCount()
{
__asm
{
rdtsc;
}
}
在x64平台上定义:

#define GetCPUTickCount() __rdtsc()

使用CallNtPowerInformation API得到CPU频率,从而将周期数转化为毫秒数,例如:

代码清单1-5

  _PROCESSOR_POWER_INFORMATION info;

CallNTPowerInformation(11, //query processor power information
NULL, //no input buffer
0, //input buffer size is zero
&info, //output buffer
Sizeof(info)); //outbuf size

__int64 t_begin = GetCPUTickCount();

//do something

__int64 t_end = GetCPUTickCount();
double millisec = ((double)t_end –
(double)t_begin)/(double)info.CurrentMhz;


RDTSC指令读取当前CPU的周期数,在多CPU系统中,这个周期 数在不同的CPU之间基数不同,频率也有可能不同。用从两个不同的CPU得到的周期数作计算会得出没有意义的值。如果线程在运行中被调度到了不同的 CPU,就会出现上述情况。可用SetThreadAffinityMask避免线程迁移。另外,CPU的频率会随系统供电及负荷情况有所调整。

总结

能帮助你了解当前线程/进程/系统效能的API大致有以下这些:

1. Sleep()——这个方法能让当前线程“停”下来。
2. WaitForSingleObject()——自己停下来,等待某个事件发生
3. GetTickCount()——有人把Tick翻译成“嘀嗒”,很形象。
4. QueryPerformanceFrequency()、QueryPerformanceCounter()——让你访问到精度更高的CPU数据。
5. timeGetSystemTime()——是另一个得到高精度时间的方法。
6. PerformanceCounter——效能计数器。
7. GetProcessorInfo()/SetThreadAffinityMask()。遇到多核的问题怎么办呢?这两个方法能够帮你更好地控制CPU。
8. GetCPUTickCount()。想拿到CPU核心运行周期数吗?用用这个方法吧。

了解并应用了上面的API,就可以考虑在简历中写上“精通Windows”了。

ScribeFire: 发布Blog的Firefox插件

其实以前就知道这个,只是那时blogspot没有解封,似乎这个插件不工作。

现在工作正常了,这一篇和上一篇都是用它发布的,还不错。美中不足是tag要自己指定,不能选。

这个其实也不怪它。我查了查Google的Blogger data API,似乎没有查询所有category的接口。

用这个的确方便了不少。

deborphan: 清除不用的库包

平时软件装装删删,总觉得会像磁盘那样有“碎片”,那就是没有用到的包。
而包又分两种,软件和库。软件比较好办,一般能很快发现,但是库就不一样了,一本很难发现。

有了deorphan就好办了,它可以搜到那些库包,用orphaner(一个deborphan的wrapper)还可以方便的删掉。




2008-04-05

blogspot再次解封

不知道是否是为了迎奥运。但是这次一解封让这个blog访问量翻了4番。让我很是吃惊:原来以前有那么多人想上而上不了。

不过依然推荐用Google Reader订我的RSS,不用担心被封的问题,也便于查找文章。

请用这个地址订阅:http://feeds.feedburner.com/coolwanglu

setterm: 控制台抓图

确切的说不是抓图,而是把缓冲区里的文字抓出来。但是仍是很使用的小程序。

一个例子 setterm -dump 1 会把1号终端的文字存成screen.dump

我也就会这么一个用法,具体还要man一下

2008-04-04

Windows is unable to find a system volume that meets it's criteria for installation

最近装Vista时,选择安装分区时总说这个错误。

网上查了一下,有很多说法,但是都跟我的情况不一样。

最后发现是要安装的分区没有boot标记,我的boot标记放在一个放grub的分区上了。

唉,windows。。。

2008-04-01

bash和sh脚本中关于测试表达式的区别

有两种
[ a = b]
[[ a == b ]]

sh 只认第一种
bash 两种都认

有个脚本我一直没改好,原因是以为是bash脚本(或者说以为sh就是bash),然后就按第二种写了,但是总是没用。 后来发现原来那个是sh脚本,而且man了一下发现sh和bash原来不是一回事。终于搞定了。