键盘上一些符号的英文读法真的让人头疼,很多根本就没有统一的念法。上葡语课时我问老师dash在葡语里怎么用,结果她不知道什么是dash,最后经过探讨我们达成共识,我问的是hyphen…… 因为我整天和程序打交道,“-”更多被读作dash,而非程序员更多读作hyphen。比较烦~~
这里简单整理一下键盘上所有特殊符号的英文读法,最后还有葡语中特殊符号的英文读法。参考资料见本文最后。
! 叹号 exclamation mark/bang
? 问号 question mark
, 逗号 comma
. 点号 dot/period/point
: 冒号 colon
; 分号 semicolon
” 双引号 quotation marks/double quote
‘ 单引号/撇号 apostrophe/single quote
` 重音号 backquote/grave accent
* 星号 asterisk/star
+ 加号 plus sign
- 减号/横线 hyphen/dash/minus sign/
= 等号 equal sign
/ 斜线 slash
\ 反斜线 backslash/escape
| 竖线 bar/pipe/vertical bar
_ 下划线 underline/underscore
$ 美元符号 dollar sign
@ at at sign
# 井号 crosshatch/sharp/hash
% 百分号 percent sign/mod
& and/和/兼 and/ampersand
^ 折音号 circumflex/caret
~ 波浪号 tilde
{} (左右)花括号/大括号 (left/right|open/close) braces
[] (左右)方括号/中括号 (left/right|open/close) brackets
() (左右)圆括号/小括号 (left/right|open/close) parentheses
<> 尖括号 angle brackets
< 大于号 less than
> 小于号 greater than
葡语中的变音符号(diacritic mark)在英文中的读法:
^ circumflex/caret
~ tilde/squiggle
´ acute
` grave
ç cedilla
参考资料:
1. http://www.codinghorror.com/blog/archives/001133.html
2. http://ascii-table.com/pronunciation-guide.php
3. http://www.learningportuguese.co.uk/language/diacritics.html
一年过了又一年,只是每年这个节日还是没变。:-)
希望明年有所改观,不过貌似我每年都这么说……
console和terminal是很容易让人迷惑的两个概念。根据wikipedia上的定义,小型计算机的console应该就是键盘加显示器;而terminal则是输入数据进去,和显示数据来源的设备,通常是一个计算机系统。
Linux下的console除了真实的硬件设备外,还有virtual console,也就是你按alt+Fn或者alt+ctrl+Fn切换到的东西。所谓虚拟就是这些console共享同一个真实的设备,只有一个活动的console才显示在前面。这些console对应的设备是:/dev/ttyN,其中1 ≤ N ≤ 63。而/dev/tty0则是指向当前的terminal;/dev/console是指向当前console,但它现在并_不是_对/dev/tty0的符号链接。更多可参考console(4)。
/dev/tty是另一个特殊设备,它指向控制终端(controlling terminal)。如果某个进程的控制终端是/dev/tty3,那么/dev/tty就指向/dev/tty3了。控制终端是什么概念?它是一个进程的某个属性,是依附带该进程上的终端。比如我们在某个终端下输入ctrl+C,那么它控制的前台进程就会收到SIGINT,而后台进程会收到SIGTTIN或SIGTTOU ,如果它们读写该终端的话。被同一个终端控制的所有进程被称为一个会话(session),会话的领导就是创建改会话的进程,其子进程也会被该终端控制。所以,1) 需要交互的命令行程序通常会从/dev/tty这个设备进行读写;2) Unix后台进程都需要在fork之后调用setsid(2),3) 需要加O_NOCTTY,当你open一个可能是终端的文件时。
另外,想要确定/dev/tty究竟是指向哪个设备,可以调用TIOCCONS ioctl。参考tty(4)。
下面是另外一个概念——伪终端(pseudo-terminal),根据pty(7)的介绍,伪终端一对虚拟设备,提供端到端双向通信的通路,一端称为master,另一端称为slave。在slave那端看到的和在真实终端看到的效果一样。所以伪终端一般被ssh等网络登录程序使用。历史上,有两套伪终端接口,一个是Unix 98伪终端,另一个是BSD伪终端。
BSD提供的接口很简单:/dev/pty[p-za-e][0-9a-f] 是master; /dev/tty[p-za-e][0-9a-f] 是slave,它们都是配好对的。这样看起来很简单,但对程序员来说不容易,要找到一个合适的终端需要一个个从头尝试。所以这种方式已经被遗弃。而Unix 98伪终端则完全不同,它始终使用/dev/ptmx作为master复制设备,然后在每次打开它的时候才得到一个master设备的fd,同时在/dev/pts/目录下得到一个slave设备。这样编程就相对容易了,根据pts(4)介绍,需要三个新的API: ptsname(3),grantpt(3)和unlockpt(3)。我们可以通过一个实例看一下如何使用:
(以下代码摘自netvirt)
C:
-
char *mptname = "/dev/ptmx"; /* master pseudo-tty device */
-
//...
-
void
-
getmaster()
-
{
-
struct stat stb;
-
-
if ((master = open(mptname, O_RDWR))>= 0) { /* a pseudo-tty is free */
-
(void) ioctl(0, TCGETS, (char *)&b);
-
(void) ioctl(0, TIOCGWINSZ, (char *)&size);
-
return;
-
} else { /* out of pseudo-tty's */
-
perror(mptname);
-
fprintf(stderr, gettext("Out of pseudo-tty's\n"));
-
fail();
-
}
-
}
-
-
void
-
getslave()
-
{
-
char *slavename; /* name of slave pseudo-tty */
-
-
grantpt(master); /* change permissions of slave */
-
unlockpt(master); /* unlock slave */
-
slavename = ptsname(master); /* get name of slave */
-
slave = open(slavename, O_RDWR); /* open slave */
-
if (slave <0) { /* error on opening slave */
-
perror(slavename);
-
fail();
-
}
-
ioctl(slave, I_PUSH, "ptem"); /* push pt hw emulation module */
-
ioctl(slave, I_PUSH, "ldterm"); /* push line discipline */
-
-
(void) ioctl(slave, TCSETSF, (char *)&b);
-
(void) ioctl(slave, TIOCSWINSZ, (char *)&size);
-
}
然后我们再来看一下glibc中对ptsname(3)的实现:
(源文件sysdeps/unix/sysv/linux/ptsname.c)
C:
-
#define _PATH_DEVPTS "/dev/pts/"
-
-
char *
-
ptsname (int fd)
-
{
-
return __ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer;
-
}
-
-
int
-
__ptsname_r (int fd, char *buf, size_t buflen)
-
{
-
-
...
-
-
if (__ioctl (fd, TIOCGPTN, &ptyno) == 0)
-
...
-
numbuf[sizeof (numbuf) - 1] = '\0';
-
p = _itoa_word (ptyno, &numbuf[sizeof (numbuf) - 1], 10, 0);
-
...
-
memcpy (__stpcpy (buf, devpts), p, &numbuf[sizeof (numbuf)] - p);
我们可以看出,实际上是调用ioctl TIOCGPTN,通过内核,而Linux内核又是通过devpts这种文件系统实现了这一切:
$ mount | grep devpts
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
这样我们终于把一切搞清楚了。:-)
ProgrammingNov 10th,2008王 聪
pthread的API一直让我感到头疼,种类多而且名字又长,今天下决心把它们理清楚。
仅从名字上来看,pthread的API可以分为这么几类:
pthread_XXX:
此类API一般是对thread本身进行管理的。共包括如下API:
pthread_atfork()
pthread_create()
pthread_exit()
pthread_cancel()
pthread_join()
pthread_once()
pthread_self()
pthread_equal()
pthread_kill()
pthread_detach()
pthread_yeild()
pthread_sigmask()
pthread_key_create()
pthread_key_delete()
pthread_cleanup_push()
pthread_cleanup_pop()
pthread_testcancel()
它还可以分出两个子类,包括pthread_setWWW和pthread_getWWW,其中有:
pthread_getconcurrency()
pthread_getcpuclockid()
pthread_getschedparam()
pthread_getspecific()
pthread_setcancelstate()
pthread_setconcurrency()
pthread_setschedparam()
pthread_setschedprio()
pthread_setspecific()
pthread_attr_YYY:
YYY一般包括:init, destory, setZZZ, getZZZ。此类API是对thread本身的属性进行管理的。共包括如下API:
pthread_attr_destroy()
pthread_attr_getinheritsched()
pthread_attr_getschedparam()
pthread_attr_getschedpolicy()
pthread_attr_getscope()
pthread_attr_getstackaddr()
pthread_attr_getstack()
pthread_attr_init()
pthread_attr_setdetachstate()
pthread_attr_setguardsize()
pthread_attr_setinheritsched()
pthread_attr_setschedparam()
pthread_attr_setschedpolicy()
pthread_attr_setscope()
pthread_attr_setstackaddr()
pthread_attr_setstack()
pthread_attr_setstacksize()
pthread_MMM_XXX:
XXX一般是上面和那个XXX集合类似的操作,但MMM一般是thread的一个工具,比如:mutex,cond等。此类API是对thread的MMM工具进行操作。共包括如下API:
mutex类:
pthread_mutex_init()
pthread_mutex_destroy()
pthread_mutex_lock()
pthread_mutex_unlock()
pthread_mutex_trylock()
pthread_mutex_setprioceiling()
pthread_mutex_getprioceiling()
cond类:
pthread_cond_init()
pthread_cond_destroy()
pthread_cond_signal()
pthread_cond_broadcast()
pthread_cond_wait()
pthread_cond_timedwait()
rwlock类:
pthread_rwlock_destroy()
pthread_rwlock_init()
pthread_rwlock_rdlock()
pthread_rwlock_timedrdlock()
pthread_rwlock_timedwrlock()
pthread_rwlock_tryrdlock()
pthread_rwlock_trywrlock()
pthread_rwlock_unlock()
pthread_rwlock_wrlock()
spin类:
pthread_spin_destroy()
pthread_spin_init()
pthread_spin_lock()
pthread_spin_trylock()
pthread_spin_unlock()
barrier类:
pthread_barrier_destroy()
pthread_barrier_init()
pthread_barrier_wait()
pthread_MMMattr_YYY:
MMM和YYY同上(spin除外),此类API是对MMM工具的属性进行操作。和上面有着密切的关系。共包括如下API:
mutex类:
pthread_mutexattr_destroy()
pthread_mutexattr_getprioceiling()
pthread_mutexattr_getprotocol()
pthread_mutexattr_getpshared()
pthread_mutexattr_gettype()
pthread_mutexattr_init()
pthread_mutexattr_setprioceiling()
pthread_mutexattr_setprotocol()
pthread_mutexattr_setpshared()
pthread_mutexattr_settype()
cond类:
pthread_condattr_destroy()
pthread_condattr_getclock()
pthread_condattr_getpshared()
pthread_condattr_init()
pthread_condattr_setclock()
pthread_condattr_setpshared()
rwlock类:
pthread_rwlockattr_destroy()
pthread_rwlockattr_getpshared()
pthread_rwlockattr_init()
pthread_rwlockattr_setpshared()
barrier类:
pthread_barrierattr_destroy()
pthread_barrierattr_getpshared()
pthread_barrierattr_init()
pthread_barrierattr_setpshared()
这还没完,还有N多的新类型,比如pthread_t,pthread_attr_t,pthread_once_t,以及随之而来的宏。。。我在这就不总结了。
最后,介绍pthread的书籍有:
"PThreads Primer". Lewis, Bill and Daniel J. Berg. California: Prentice Hall.
"Pthreads Programming". B. Nichols et al. O'Reilly and Associates.
"Programming With POSIX Threads". D. Butenhof. Addison Wesley
"Programming With Threads". S. Kleiman et al. Prentice Hall
ProgrammingNov 8th,2008王 聪
网上有个查询的网站,可惜什么结果都查不出来!靠!我实在看不下去了,动手写一个python程序来搞定,不过仍有局限性,那就是只能查询.iso.org子树。。。啥也不说了,上代码!
PYTHON:
-
#!/usr/bin/env python
-
-
import os,sys
-
import string
-
import re
-
import urllib2
-
-
-
if __name__ == '__main__':
-
-
if len(sys.argv) != 2:
-
sys.stderr.write("Please provide one OID number or string to lookup.\n");
-
sys.exit(1)
-
-
flag = 0
-
found = False
-
-
r = re.compile('^[0-9\\.]+$')
-
if r.match(sys.argv[1]):
-
r = re.compile('^1\\.3')
-
if r.match(sys.argv[1]):
-
flag = 1
-
else:
-
sys.stderr.write("Please provide the full OID number under .iso.org!\n")
-
sys.exit(1)
-
-
try:
-
req = urllib2.Request('http://www.kix.in/plan9/mirror/sources/contrib/gabidiaz/root/lib/ndb/snmp')
-
resp = urllib2.urlopen(req)
-
oid = resp.readline()
-
name = resp.readline()
-
while oid and name:
-
if flag == 1:
-
if oid.find(sys.argv[1]) != -1:
-
print name
-
found = True
-
break
-
else:
-
n = name.lower().find(sys.argv[1].lower())
-
if n != -1:
-
print oid
-
found = True
-
if n+len(sys.argv[1]) <len(name)-1:
-
print name
-
oid = resp.readline()
-
name = resp.readline()
-
if not found:
-
print "Not found!"
-
sys.exit(0)
-
except IOError:
-
sys.stderr.write("Probably you don't have Internet.\n")
-
sys.exit(1)
ProgrammingNov 8th,2008王 聪
可参考ASN.1关于octet string的介绍。
BASH:
-
#!/bin/bash
-
-
i=1;
-
while(($i<=${#1}))
-
do
-
printf "%d" "'$(expr substr $1 $i 1)"
-
if (($i != ${#1}))
-
then
-
echo -n '.'
-
fi
-
i=$((i+1))
-
done
-
echo
-
exit 0
上面使用了一个鲜为人知的小技巧,而且不仔细看也不太容易察觉。
此脚本可以这么用(假设此脚本被存为to_string.sh):
$ snmpwalk -v2c -c test 192.168.90.72 .1.3.6.1.4.1.8072.1.3.2.4.1.2.${#STRING}.$(./to_string.sh $STRING).1
这是我见过的最牛的解答:
我昨天晚上做梦的时候好像把这个事情想清楚了。现在又不记得了。
你简直是太有才了!!!!!!!!!!!!!!!!
上个周末真的玩疯了。
因为bruno要去瑞士了,上个周五晚上就算是为他送行了。先是在一个餐馆一起吃饭,critcial links来了很多人。那个餐馆的菜并不是很好,不过谁有在乎呢,大家在一起聊得开心就好。最后,我被灌了四杯葡萄酒,加上我自己那瓶啤酒,结果下来真的有点醉了,不过还好能撑得住。吃完都十二点多了,本以为这就完了,没想到疯狂这才开始……
然后又跟着他们去了另一个酒吧去接着喝,这次我比较聪明,没跟着他们喝那种带酒精的饮料,我叫了两瓶红牛,没想到它效果那么好,喝了一瓶就已经完全清醒了。marco说我喝两瓶忒多了,整个晚上都会睡不着了,我不信。大约坐了一个多小时后我们就去另一个地方,我还在想怎么还非得换另一个地方继续喝,在这里不是一样么?没想到这次去的是舞厅……这时又来一些人,包括几个HR的美女。进了舞厅才发现那真是一个彻底疯狂的地方,里面响着疯狂的音乐,而且挤满了年轻人,闪烁的彩灯,DJ师,调酒师,各种各样的美女……管它呢,我们这些人围成一圈也跳了起来。说实话,跳舞其实并不难,简单地来说就是扭扭屁股,甩甩胳膊,不过想要跳好可真就不容易了。我跟着另一个bruno和marco慢慢地学着跳,感觉真的很疯,不过也感觉真的很轻松!!好久没能这么释放自己了,真的很开心。我们就这样一直玩到舞厅关门,都快凌晨五点了……
“送君千里终需一别”。最后我们不得不和bruno真的道别了,我以后再也听不到我对面这个bruno对着我另一边叫另一个bruno了,再也不能看着他那熟练卷烟的动作说他是cigarette machine了……希望他在瑞士过得更好,一路顺风!
有时候,唯一保持清醒的办法就是发点儿疯。:-)
Americans are NOT stupid
http://www.youtube.com/watch?v=fJuNgBkloFE
同事推荐给我的,里面那个KFC的都快把我们笑翻了……里面的美国人不是一般有才~~
祝大家周末愉快! 
ProgrammingOct 31st,2008王 聪
在 arch/x86/include/asm/uaccess.h 中有这么一段代码:
#define __range_not_ok(addr, size) \
({ \
unsigned long flag, roksum; \
__chk_user_ptr(addr); \
asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \
: "=&r" (flag), "=r" (roksum) \
: "1" (addr), "g" ((long)(size)), \
"rm" (current_thread_info()->addr_limit.seg)); \
flag; \
})
这段汇编写得很有技巧性,充分利用了sbb指令和carry flag,值得你仔细体会一番。还有一个关于sbb的技巧:
sbb eax,eax
sbb eax,0FFFFFFFFh