以下是一次外训课程《linux c 编程与内核调优》的听课笔记。
这里记的比较琐碎:
1. 要深入理解linux, 可以尝试搭一个 LFS
2. printf/scanf的返回值,返回输出的字符个数和匹配个数,不包括(NULL)
3. fd为kernel File对象指针数组的下标。
4. 所有的syscall都不能假定成功。 尤其要注意read和write的返回值。
5. open(2) 可以提供两个或者三个函数,内部通过变参实现(通过多加参数的方法是可以测试出来,因为变参对于多余的参数不会报错)。
open 常见错误的是忘记第三个参数。 O_EXCL不能用于NFS
6. memcpy 要求区间不能重叠。
memmove可以。
7. truncate/ftruncate用于把文件truncate到指定长度。 (如何将一个文件的第10行?)
8. fseek 不建议用,因其第二个参数为long型,不可移植。应为off_t
建议fseeko 和 lseek,都为off_t. 大文件需要#define _FILE_OFFSET_BITS 64. 或者在Makefile中用-DFILE_OFFSET_BITS指定
9. dup的作用。 5 = dup(3). 表示fd 5和3都指向同一个kernel file对象。
10. 文件的size和space是不同的属性,因为unix支持空洞文件. stat /tmp/bigfile 可看文件的相关属性。
stat中,文件的三个时间:
st_atime(latest access time), st_mtime(lastest modify time), st_ctime(lastest inode change time)
linux无法记住file的create time
11. linux文件系统中,比较先进的 XFS, reiserfs. 但稳定性没有ext3好。
12. 访问文件的目录, 推荐API: glob(3) , 匹配通配符。glob("*"), glob*(/tmp/.*") ...
13.通过uid获取用户名: getpwuid/getpwnam, 返回的struct passwd放在静态区,非线程安全,不可以重入。
14. crpty(key, salt), 将key 转化为passwd文件中的Hash值。其中Hash串的规律:
非'$'开头说明是DES加密
'$1' 开头说明是MD5加密
'$2'为其他算法。
15. mktime(struct tm *tm) 的参数不是const, 有副作用:会将tm中的时间合法化。
通常的用法是利用其副作用,例如计算100天以后的日期:
now = time(NULL)
tm = localtime(now)
tm->tm_mday += 100;
mktime(tm);
接下来得到的就是日期。
16. 参数匿名的临时文件 , tmpfile
17. 关于64位的地址空间, 可以用pmap查看 `pidof syslogd`, 看以看到其地址。
64位地址空间目前在X86_64上只是使用了最低的128T和最高的128T(kernel使用), 其实只用了48位,49~64位的值和第48位相同。
18. 参数传递:32位机器函数调用时的参数通前三个通过register传递,后面通过stack, 而64位机器全部通过register传递
可以通过 strace ./a.out 参看一个程序的装载过程,装载程序时用得最多的是mmap
19. 链接时的动态库使用 -l 参数指定。 而运行时装载动态库使用 dlopen等函数。
21. longjmp/setjmp 实现C语言的跨函数跳转,注意,凡setjmp函数的局部变量都必须是volatile.
通常用于两个地方: 递归算法的快速返回和异常处理。
22. fork 和exec 之前一定要fflush(NULL), 否则会导致脏数据
23. linux平台提供了直接使进程成为daemon的函数: daemon,
另外注意APUE中的错误, 成为daemon进程之前,其所有的fd不需要关闭。
24. 信号不可靠问题,在某些老的Unix平台上存在。 因为其signal函数是一次性的,而现在的linux和Unix是永久有效。
25. 信号会打断阻塞的函数,一定要注意检查返回值,例如read/write. 注意manual中的说明
26. sleep/usleep函数不会屏蔽信号。当需要屏蔽时,可以用select或者nanosleep来替代
27. SIGKILL 和SIGSTOP 无法屏蔽,但是可以设置signal handle
信号的响应时间: 进程被中断或者其他方式进入内核后,在内核处理完毕再次继续运行程序之前(回到用户态),内核会
查看进程的信号并处理。
28. kill -l 查看所有信号,其中实时信号按投递时间的顺序响应
29. sigqueue 相比kill, 可以在发送信号时带个value,以区分不同的信号源。
30. 建议将: sigprocmask(); pause(); sigprocmask(); 换成sigsuspend原语
31. pthread_cleanup_pop/push 的作用与进程的atexit作用类似。 可以配合起来cancel一个线程,但要注意线程是有cancel点的。
36. 文件锁与线程锁的区别:
1)mutex不区分加锁者, 而文件锁区分
2)同一进程可重复加锁,但mutex不可以。
一道编程题: 有四个线程,每个线程分别频繁地输出'A', 'B', 'C', 'D', 如何调度,使得每个线程都能均匀地执行,以使得输出为:ABCDABCDABCD。。。
解答: 四把锁给四个线程,每个线程运行之前加锁自身, 运行完后解锁下一个线程的锁。
37. 内核调优参考书: RH422, Redhat Enterprise System Monitoring and Performace Tuning
38. man -k gettime 可以查询以gettime开头的函数,用于记不住函数名的时候用。
阅读(712) | 评论(0) | 转发(1) |