0

Comments

由于要测试一些代码,其运行结果会受到多核并行的影响,所以希望能够调整使用的 CPU 数量。网络上之前看到的方法是在内核的启动参数上添加一个 maxcpus,但是如果这样的话每切换一次都要重启一次,是在太麻烦了。想想 Linux 应该是很强大的,所以可以动态修改 CPU 数量才对。

无意中看到 Linux 代码的 Documentation 文件夹下有个文件叫做 cpu-hotplug.txt,于是就看了一下,发现可以在 /sys/devices/system/cpu 看到代表各 CPU 的文件夹按照 cpuX 的命名方式,如 cpu0、cpu1、cpu2 等。这些文件夹里面有一个 online 文件,如果其值为0则禁用该 CPU,如果为1则启用该 CPU。注意,这里需要 root 权限哦。

因为我只要在单核和多核之间切换,所以我写了两个脚本放在 /usr/local/sbin 里面:

singlecore

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
 
cpus_dir="/sys/devices/system/cpu"
 
for cpu in $(ls "$cpus_dir" | grep 'cpu[0-9]\+')
do
	cpu_online="$cpus_dir/$cpu/online"
	if [[ -e "$cpu_online" && $(cat $cpu_online) = 1 ]]
	then
		echo 0 > "$cpu_online"
	fi
done

multicore

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
 
cpus_dir="/sys/devices/system/cpu"
 
for cpu in $(ls "$cpus_dir" | grep 'cpu[0-9]\+')
do
	cpu_online="$cpus_dir/$cpu/online"
	if [[ -e "$cpu_online" && $(cat $cpu_online) = 0 ]]
	then
		echo 1 > "$cpu_online"
	fi
done

之后需要切换的时候,只要运行 sudo singlecore 或者 sudo multicore 就可以了~

顺便说一句,我当时在想,如果我禁用了所有的 CPU 会怎么样呢?结果发现 cpu0 是没有 online 文件的,也就是 Linux 至少保证一个 CPU 处于可用状态。

< ,, >

安装配置 LXR

1

Comments

专业课学习操作系统,满心欢喜地以为可以是 Linux 代码导读,结果选用了一本八十年代的教材,介绍 UNIX v6 的。于是自己从图书馆借来了内核开发的入门读物《Linux 内核设计与实现》。既然是介绍内核的书,自然少不了代码,但是书中又不可能将每个提到的代码的相关信息全部写出来,这时就得自己去查看代码。查看代码的话,虽然 Linux 的代码可以很容易地得到,但那来看终归有些麻烦,各种调用需要查找半天。于是想起了很有名的一个网站 LXR:http://lxr.linux.no,Linux 交叉引用。这个网站好是好,就是网络原因速度太慢,于是就想自己装一个。

先说一句,下面的安装环境都是64位 Gentoo。

最开始找到了 LXR Cross Referencer 这个项目,一看最后更新时间还挺新,看起来是一直都还在维护的。然后在 Gentoo 的网站上查到 LXR 是可以直接用 portage 安装的,于是安装,安装相关的包,最后放弃了。出于什么原因我也不记得了,最后一个原因肯定是不好看,肯定达不到上面那个网站的效果,所以就放弃了,到那个网站上去下载 LXR 分出来的版本 LXRng。(话说这个 ng 不会是表示 next generation 吧?)
Read the rest of this entry »

< , >
1

Comments

如果你也用 Gmail,他可以让你轻易拥有无限多的子邮箱,发给这些邮箱也就等于发给你的邮箱。这有什么意义呢?很简单,你可以在每个地方注册的时候都使用不同的邮箱,这样当你收到垃圾邮件广告邮件,你就可以知道是从哪里来的了~再结合 Gmail 强大的过滤器,你也可以针对性的进行屏蔽~

Gmail 事实上支持两种方式来扩张你的邮箱,第一种是在你的用户名后面加上“+”和任意字符串,比如我的邮箱 quanxunzhen@gmail.com(我这邮箱无所谓了已经嗯),如果我想要识别不同的网站,比如豆瓣,我可以直接在豆瓣的注册邮箱里填写 quanxunzhen+douban@gmail.com,所有验证邮件都可以发给我,我如果不想申请一个新邮箱却想注册个豆瓣小号,也可以再写 quanxunzhen+douban2@gmail.com。

当然,支持上面的方式固然是最好的,但遗憾的是很多网站并不支持带加号的邮箱,那就要稍稍麻烦点了。

根据 @fanzeyi 的说法,Gmail 的邮箱是自动忽略点,也就是“.”的,也就是说对于我上面的邮箱,如果写为 quan.xun.zhen@gmail.com,或者 ..quanxunzhen..@gmail.com,我照样可以收到。而且这样写法的邮箱通常不会被屏蔽,因为点毕竟是邮箱必备的部分。

但是这样加点有一个问题,就是我们无法像第一种方式那样很容易的区分来源,因此我们不得不进行某种编码。

顺序编码

第一种编码的思想大体上是按照传统的数据库中记录的自增 ID,转为二进制表示,具体的说就是,比如我这个邮箱有11位,那么我们可以以中间有打点或者没有打点作为二进制位中的0和1,比如就可以如下表示:

1
2
3
4
5
0 quanxunzhen
1 quanxunzhen.
2 quanxunzhe.n
3 quanxunzhe.n.
29 quanxun.z.h.en.

这样……

但是这样总编码数也就 2^len(email)+1 种,对于我邮箱这么长,也仅仅4096种,总归有点少。(其实也不少了吧喂……)

于是我们考虑一下扩张的方法。

其实扩张很简单,因为任意两个字母之间可以插入的点是任意多的,我们可以利用这一点按照一定的协议来编码,比如我们规定第一个字符之前如果有 n 个点,则之后每个字母之间最多可以有 n+1 个点,这样当第一个字符前有 n 个点时,最大可以编码 (n+2)^len(email) 种,如果规定这里每次数字都是从上一次结束的数字开始,编码就不会重复了,而且可编码的范围大大增加,却又没有太多的增加点的数量。对于我的邮箱来说,前面一个点也没有时可以有 2048 种,有一个点时可以有 177147+2048 种,有两个点时可以有 4194304+177147+2048 种,我相信是用不完的了……

事实上基于此还可以延伸出各种各样的编码方式~

字符编码

不过上面的方法总归不那么直观,而且如果想追踪来源,还要建表,表的同步还是个问题,所以这个问题还是挺大的……于是我有了第二种想法,可以把注册地的名字嵌入到里面~

最基本的想法是根据字母序,比如在 Arch 论坛注册我们可以把 Arch 变成数字串 0 17 2 7,插入进去变成:

1
qu.................a..n.......xunzhen

不过我们可以明显的感觉到很蛋疼……Arch 还算好的,如果是新浪(Sina -> 18 8 13 0)或者淫淫网(Renren -> 17 4 13 17 4 13)就更蛋疼了……

但是我们感觉到不是这样的,我们完全不需要那么多字母其实也可以认出他们来不是么?比如淫淫网我们可以用 rr,或者原名校内的 xn,新浪就 sn 什么的,这样需要的字母就少了,我们就可以利用变换进制的优势了~26对于二进制位需要5位,对于3进制恰好只要3位,当然算起来如果你的邮箱够长肯定还是用二进制可以增加的更短一些,对于我来说就是如此,比如上面的就可以这样变化了:

1
2
3
rr -> 17 17 -> 10001 10001 -> q.uanx.u.nzhe.n
xn -> 23 13 -> 10111 01101 -> q.ua.n.x.un.z.he.n
sn -> 18 13 -> 10010 01101 -> q.uan.xun.z.he.n

如果三进制的话,我的 upsuper 也可以容下了:

1
2
3
rr -> 17 17 -> 122 122 -> u.p..s..u.p..e..r
xn -> 23 13 -> 212 111 -> u..p.s..u.p.e.r
sn -> 18 13 -> 200 111 -> u..psu.p.e.r

看过去好多了~

我们还可以发挥其它的想象力,比如找寻标识中的字母频率然后构建一个霍夫曼编码树什么的~

我能想到的暂时只有这么多了,各位还有什么更有意思的想法么?

5

Comments

上周六参加了好久没有参加的的 SHLUG 月聚,恰逢 TualatriX 也带团来上海。自由讨论的时候,我看到 TualatriX 的终端十分色彩斑斓,便询问,他给我们展示了他的 bash 的两个特色功能:1、当上一条命令返回结果不为0时显示返回值并高亮显示提示符;2、自动检测git分支。他说这个在他的博客上都可以找到,今天想起来去找了一下,发现了这篇:史上最强的PS1 | I’m TualatriX,感觉满强大的。

不过,说实话,我觉的这个还不够完美,原因有二:一是我发觉高亮显示的时候那个配色相当不怎么样,二是我本来就讨厌提示符太长,这样一下就更长了……于是我就想起 ghosTM 的 zsh 里面有一些信息是放在右边的,我想把返回值也扔右边去,并且是右边上移一行。此外,由于很少使用 git,所以检测 git 分支的功能也就不需要了~

先放一个最终效果图:

然后直接写出了我的新的 PS1:

1
PS1='`a=$?;if [ $a -ne 0 ]; then a="  "$a; echo -ne "\[\e[s\e[1A\e[$((COLUMNS-2))G\e[31m\e[1;41m${a:(-3)}\e[u\]\[\e[0m\e[7m\e[2m\]"; fi`\[\e[1;32m\]\u@\h:\[\e[0m\e[1;34m\]\W\[\e[1;34m\]\$ \[\e[0m\]'

非常复杂唉……让我自己再看一次都头晕……
Read the rest of this entry »

< >
1

Comments

当小白鼠绝对是一件得耐得住折腾的事情……当然,这看起来和RC不RC似乎并没有太大的关系,作为在普罗大众之前开始接触桌面Linux的一员,绝对可谓是小白鼠了。

说 Ubuntu 10.10 的安装界面确实是做的不错了,而且还能自动识别需要的私有驱动。不过有一点让我比较无语的是,在我还没有联网的时候,他找到我的无线网卡的私有驱动,但是下载安装不了……所以我不得不接上网线安装。安装过程比较顺利,除了似乎选择硬盘分区的时候十分卡以外,其它的地方还是很满意的,包括一边复制文件一边询问一些详细配置、一边复制文件一边给出 Ubuntu 的特性介绍这样。另外,正如 Canonical 公司之前承诺的那样,中文成为了 Ubuntu 10.10 的官方语言,安装完成后,全部中文界面,并且自动安装好了 ibus-pinyin。不过,Firefox 却意外的成为异类,仍然是英文(先在不知道什么时候已经突然变成中文了)。此外还有一点就是,很希望 ibus-sunpinyin 能尽快成为默认的,因为确实比 ibus-pinyin 好很多的感觉。

一安装完问题就来了,没法启动!后来几经周折,发现原因是安装的时候莫名其妙的把我的安装U盘识别为 sda 而硬盘识别为 sdb,并且安装程序还把这个写进了 fstab 里面。理论上说 Ubuntu 应该自动写入 fstab 的都是 UUID 才对,这次却写了 /dev/sdXY 进去,着实让人感到奇怪。通过我的修复盘手动修改了 fstab 以后终于成功进入了,后面就改成了使用 UUID 了,保证不会出问题……我去网上一搜,没有发现有人遇到同样的问题,我就到 Launchpad 报告了 bug:installer identified hard drive as sdb led to the new system unbootablity。话说我的英文这么差,各位看到有什么语法错误之类的,那也是很正常的了……提交 bug 也算是我对开源的一点贡献了吧……

然后安装了 nVidia 的私有驱动 256.53,成功开启了各种 Compiz 特效,非常赞,而且效果相当不错。不过问题也随之而来:开机画面惨不忍睹……这是个很纠结的问题,你说那么漂亮的一个开机画面,怎么就被个驱动整成那模样……接着就在 Ubuntu 中文论坛上找到了解决方案。这个方案比较复杂,我就直接给链接好了:Ubuntu 10.04 安装Nvidia显卡后开机花屏完美解决(图解),可以看到这是 10.04 时代遗留下来的问题……不过这个方案解决还算完美,至少开机画面是漂亮了不少的。不过这个事情有一个副作用,就是切入切出 tty 变得格外缓慢。于是在这栋楼的47楼发现了解决方法,这个就简单了。因为那个作者没有写出详细的做法,我就简单说一下。在解决的第一步肯定要用到 hwinfo –framebuffer 这个命令,先在仍然用这个命令,察看你选择的那个分辨率的编号,比如我选择的模式是“Mode 0×0318: 1024×768 (+4096), 24 bits”,那么我需要的编号就是 0×0318 = 792,就是十六进制和十进制的转换咯。然后修改 /etc/default/grub,把刚才改过的

1
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nomodeset video=uvesafb:mode_option=1024x768-24,mtrr=3,scroll=ywrap"

修改为

1
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nomodeset video=uvesafb:mtrr=3,scroll=ywrap vga=792"

然后打开 /etc/initramfs-tools/module,同样去掉 mode_option=…. 的那个部分保存。然后还是

1
2
sudo update-initramfs -u
sudo update-grub

就可以了。然后再重启以后,切换 tty 慢的问题也算是初步解决了。

接下来遇到的问题就更囧了,gVim 和 OpenOffice.org 里面各种花屏,字体混乱。这个问题倒是很多人遇到过了,在 Launchpad 这个 bug 已经被先后3次提交到了不同的软件包,包括 nvidia 驱动包openoffice.org 包vim 包……看了一遍里面的各种提示,发现有两种方法可以解决这个问题:第一种是使用 metacity 替换 compiz,具体的做法就是 Alt-F2,输入“metacity –replace”,替换速度还是挺快的,替换后就解决问题了,缺点是切换过去以后各种桌面效果就没有了。当然,想要切换回 compiz 感受桌面效果的时候,再按 Alt-F2,输入“compiz –replace”就可以了。第二种是调整字体配置,也就是在 系统/首选项/外观/字体 里,把下面的次像素平滑修改为上面的最佳形状。说实话,最佳形状看过去没有次像素平滑漂亮,不过问题是可以解决的。后来在那个 bug 反馈中有人提出,在选择最佳形状后点击“细节”,在微调内选择“轻微”可以改善显示效果,并且不会导致 gVim 和 OpenOffice.org 花屏了,我试了一下确实如此,不过总觉得是不是可能还有问题……现在暂时使用这个了……

嗷……现在暂时遇到了这些问题,很纠结的呢……所以说当小白鼠还真是一件得耐得住折腾的事情呢……

< ,, >
2

Comments

前一段由于收了某个 zip 文件,用 Ubuntu 自带的归档管理器打开,哎呦,那真不是一般的蛋疼……因为里面全是中文文件名,那个乱码啊……

于是我就下决心要解决这个问题。

虽然我的系统还在 9.10,但看到网上一篇文章教人如何在 10.04 中解决这个问题,我就了解了,这个问题至今没有解决。那么什么叫做“半完美”呢?大概意思就是说,对我来说差不多完美了,不过还是很可能出问题的……
Read the rest of this entry »

< ,,,, >
1

Comments

今天突然有兴致来对比一下我在过去的一年中主要学习的两种语言,Python 和 Erlang,他们都是很神奇的语言。不过,在我看来,更神奇的是,这两种语言几乎是完全对立的!

下面我弄了张表格来对比他们:

名称 Python Erlang
主要范型 面向对象 函数式、面向并发
开发者 Python 基金会 商业公司 爱立信
文件编码 在 Python 2 中默认为 ASCII,Python 3 中默认为 UTF-8,但都可以制定任意编码。 默认为 Latin-1,不允许指定文件编码。不过事实上编译器并不会在意文件中是否存在“不正确”的字符。
变量 几乎什么都是变量,变量都可以不断变化,无论是值还是类型。甚至你可以改变 True 和 False,让他们颠倒。(当然,也有例外,如 None,我至今没找到改变他的方法) 且不说原子是显然不可变的,任何一个变量被赋值之后,他的值也是不可变的,这是所谓变量绑定。(单次赋值)
字符串 拥有完善的字符串支持,在 Python 3 中这更是发挥到了极致。 根本不存在字符串类型,一切字符串都是字符列表,因此就更没有什么强大的字符串处理函数了。
列表 可以根据下标索引快速获取列表任意位置的内容。 考虑效率的话,只能从列表的头部摘取内容。
模块 依据文件系统的文件分布构建层级式的模块体系,使用模块前必须声明将模块引入当前名字空间。 所有模块是平行的,在同一层中,模块名称强制与文件名相同。使用模块时模块必须已经被编译,Erlang 将会自动寻找模块并读取。
并行 通过 GIL 这一全局锁将所有多线程操作退化为单线程操作,不存在任何并发性。(不过 Python 正在尝试加入新的模块来改变这一问题) 天生就是面向并发的……用他仅做顺序编程是一种莫大的浪费……
C 接口 使用 Python.h 编写接口,编译为动态链接库,运行时调入 Python 内使用。 编写外部程序,通过标准输入输出与 Erlang 主进程交换数据,在 Erlang 进程空间外单独运行。(也有一种在进程空间内运行的接口,不过不推荐使用)
函数重载 不支持任何形式的函数重载,但支持可选参数。 支持参数数量不同的同名函数,但不支持可选参数。而且基于模式匹配,支持同一函数的不同分支的定义。
数据库 内置了通用的 SQLite 数据库支持,可以通过 SQL 语句进行数据库操作,储存的信息限制在文本、数字等几种。 内置了专用的 Mnesia,可以与 Erlang 无缝衔接地储存任何内容,通过 Erlang 的 qlc 模块不使用 SQL 语句进行数据库操作。(NoSQL)
代码热替换 支持使用 reload 函数重新载入一个模块。 模块的新版本被编译后任何调用即采用新的代码。

可以看到这两种语言真的是非常非常不同,我想这和他们的设计初衷和适用范围是很有关系的:Python 大多数时候被用于快速的原型开发、用作胶水语言、创建小型桌面级应用程序;而 Erlang 则在一开始就被用在电信,这一对容错、并发要求较苛刻的领域。

不过我还是觉得,这两种语言都是非常优美的,以他们自己的专长而言。不过 Python 已经非常不错了,Erlang 在我看来则还有很大的发展空间~

PS:以上仅仅是就我自己的了解给出的一些对比,疏漏和错误在所难免,也希望看到了及时告诉我~

< , >
2

Comments

我们的 C++ 老师给我布置了 C++ 的大作业来替代其他同学交的无聊题目。大作业的第一题就是完整的高精度库,并且要求使用运算符重载。因为原来用 C 写过,这次写,思路上没有太大问题,不过全部程序被我 C++ 化了,代码看过去很诡异……呃……

我自己的机子上,自然使用 g++ 编译,不过我猜老师会要求 VC6 能够编译……我就用上次安装的 VC6 编译了一下,发现好几个错误和无数警告……其实也是我意料之中的。
Read the rest of this entry »

< ,,,,, >
1

Comments

什么叫 BMP 到 HTML 呢……?就是生成一个网页,里面用不同颜色的字符拼出那个图片……很无聊的功能嗯,而且原理上说,生成的 HTML 文件如果要表现整个 BMP 的所有细节,大小肯定大大超过原 BMP 文件……

为什么会做这个呢?主要是受到我们 C++ 老师的启发,尝试去做的。不过我没有用 C++ 写,而是选用了寒假学的 Erlang,这也是我写的第一个 Erlang 程序。

为什么会选用 Erlang 呢?主要是基于两点原因:1、寒假学了半天,一点都没有练过,就拿这个来练练;2、看中了 Erlang 强大的模式匹配和比特语法。比特语法在 Erlang 里面原来是用来解决网络传输协议中的二进制数据的,不过这里拿来处理二进制文件着实是一个很好的选择~不过其实 Erlang 真正最重要的特性:面向并发,我完全没有用到,而是继续使用了顺序编程。主要是,BMP to HTML 没什么可以并发化的,而且就算并发了,也是大传输小计算,并没有什么很大的优势。因为是第一次写 Erlang 程序,如果有 Erlang 高手路过,还请多多指点咯~

另外一点,为什么选用 BMP 这种几乎被人抛弃的格式呢?因为最容易呗……而且我这里还用了 BMP 中最简单的一种:真彩色无压缩格式。这是最直接的图形表示方式了,就是一个点一个点的,每个点三个字节表示一种颜色。所以还是很简单的。

先看看最后的效果:

下面说干就干。
Read the rest of this entry »

< ,, >
1

Comments

我发觉研究的东西多了,就会看到各种神奇的 Bug……

今天写的这个 Bug 是关于 Apache 的 Rewrite 模块的。先来看一个很正常的 Rewrite 规则:

1
2
RewriteCond %{REQUEST_URI} \.u$
RewriteRule ^(.*)\.u$ $1

这个什么意思呢?用过的人一定看得出来,就是把一个 .t 结尾的请求发送到一个去掉 .t 的文件上面。比如我如果请求 upsuper.u 就会自动调用 upsuper 这个文件来返回。这没有什么疑问。

然后,我们发现,.u 文件浏览器不知道是什么,而 upsuper 这个文件在服务器上又是没有类型的,于是 Apache 不知道告诉浏览器(或者错误地告诉了一个)MIME-Type。这样即使这个文件是个网页,浏览器上也会出现下载提示或者当作纯文本直接输出。

翻阅了一下 Rewrite 模块的资料,我们了解到可以使用 T 这个标志符来强制指定 MIME-Type 类型,于是规则变成了下面这样:

1
2
RewriteCond %{REQUEST_URI} \.u$
RewriteRule ^(.*)\.u$ $1 [T=text/html]

可是无效!

Bug 开始出现了~
Read the rest of this entry »

< ,, >