虽然handle和handler只有一个字符之差,但在程序员的世界里,含义却大相径庭。
1. 先说说handle
北京话说"一边儿玩儿去,玩勺子把儿去","勺子把儿"说的就是handle。二将handle翻译成"句柄"绝对是一个相当文雅相当阳春白雪的翻译,因为太文绉绉啦,很多文化底蕴不够的码农就看不大懂了或者望而生畏。为了弄明白为什么这么翻译,我费了点周折。 句柄者,弯杆杆儿,弯把手儿也。注意: "句"为"勾"的通假字,句柄应该读作gou柄才是。《说文解字》对"句"的解释是"句, 曲也"。《说文解字注》(作者:清代学者段玉裁,简称"段注")里是这么说的"凡曲折之物,侈为倨,敛为句。考工记多言倨句。" 因此,如果将handle翻译成大白话"玩把手儿",进不得教科书,页写不进那些晦涩乏味的计算机图书。那么,程序员如何理解handle呢?简单来说,handle就是一个"带把儿"的物件的那个"把儿"。
例如:
进程号pid就是一个handle,
文件描述符(fd)也是一个handle,
系统调用号(syscall num)仍然是一个handle,
... 不胜枚举。
在操作系统中,一切对用户来说是透明的但是操作系统内核看得懂的无符号整数(unsigned int)都可以被看作是handle。
在操作系统设计与实现中,联系内核态和用户态,靠的就是一个个无符号整数。因为用数字来做通信密码(比如:操作码,错误码等)实在是太方便了。而且,一个unsigned int占4个字节,可以表征的通信密码总数为2^32(=4G, 约40亿)。 如果不用无符号整数来做通信密码,而是采用可读性很好的明文(字符串"string")来做通信,那是何等的情何以堪?! 因为,计算机做字符串比较的代价要远远大于无符号整数的比较。
好啦,扯远了,一句话,下次看到"句柄",不用害怕啦。因为它就是handle, 说白了就是个跟一个黑盒子进行通信的密码。一旦通信密码传给了黑盒子,黑盒子怎么具体操作,对持有handle的用户来说,完全不用关心。"不看过程,只看结果"就得了。
2. 神马是handler
在编程中使用过信号(signal)的朋友一定跟handler不会陌生。 例如:
$ man -s2 signal NAME signal - ANSI C signal handling SYNOPSIS #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); ...
hanlder就是一个回调函数(callback)。当某个事件到达时,事先注册的handler会被接收到事件的主体调用。 示例代码:
o foo.c
1 #include <stdio.h> 2 #include <signal.h> 3 #include <unistd.h> 4 5 unsigned int g_exit = 0; 6 7 static void foo_handler() 8 { 9 printf("signal USR1 is caught, %s is called\n", __func__); 10 g_exit++; 11 } 12 13 int main(int argc, char *argv[]) 14 { 15 signal(SIGUSR1, foo_handler); 16 17 while (!g_exit) 18 sleep(10); 19 printf("good bye\n"); 20 21 return 0; 22 }
o 编译并测试
T1$ gcc -g -Wall -m32 -o foo foo.c T1$ ./foo T2$ ps -ef | grep foo | grep -v grep veli 9239 2293 0 21:04 pts/7 00:00:00 ./foo T2$ kill -SIGUSR1 9239 The output from T1 looks like: T1$ ./foo signal USR1 is caught, foo_handler is called good bye