Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chenzx/7668ae894b8328d814ff to your computer and use it in GitHub Desktop.
Save chenzx/7668ae894b8328d814ff to your computer and use it in GitHub Desktop.
Linux系统编程(第2版)笔记 (本书基本上就是Linux C API的简单使用说明,入门级别的)
Linux系统编程(第2版)
跳转至: 导航、 搜索
目录
1 入门和基本概念
2 文件I/O
3 缓冲I/O
4 高级文件I/O
5 进程管理
6 高级进程管理
7 线程
8 文件和目录管理
9 内存管理
10 信号
11 时间(这里谈不上系统编程了,就是C库API)
12 附录A C语言的GCC扩展
13 附录B 参考书目
入门和基本概念
文件I/O
read(): EINTR EAGAIN
其他错误:EBADF EFAULT EINVAL EIO
Append模式:每次write之前的文件位置更新是原子操作
延迟写:/proc/sys/vm/dirty_expire_centisecs
O_DIRECT:长度、偏移均应是底层设备扇区(一般4KB)的整数倍
lseek --> pread/pwrite:避免了多个线程操作同一个fd时的竞争
p51 select()和poll()都是水平触发,不是边缘触发
poll() vs select()
对值较大的文件描述符,后者要检查集合中的每个位,而前者只是个链表(但是复杂的数据结构怎么传递进内核的?)
select()返回时重新创建fd_set,而poll()会把events和revents分开
VFS、页缓冲、页回写
缓冲I/O
p72 ungetc:只要有足够的内存,Linux允许无限次放回
p72 rewind(stream) => fseek(stream, 0, SEEK_SET)且清空错误
p80 fflush()只是把用户缓冲数据写入内核缓冲,不保证最终写到物理介质上(fsync)
setvbuf:_IO{N,L,F}BUF 无缓冲/行缓冲/块缓冲
flockfile:允许递归加锁?
高级文件I/O
向量I/O?:readv/writev
epoll(Linux专有?)
epoll_create1
epoll_ctl(epfd, op, fd, event) <-- 这个API看上去够复杂的了
event->events |= EPOLLET; 边缘触发?(非阻塞I/O,需要仔细检查EAGAIN?)
epoll_wait
mmap
long page_size = sysconf( _SC_PAGESIZE ); //或getpagesize()、直接PAGE_SIZE
p109 库函数如glibc,经常使用mremap()来实现高效的realloc()
POSIX.1 mprotect() 要么只读,要么只写,要么可执行,不能同时
madvise():准确预读?(除非是POSIX_FADV_RANDOM)
synchronnous vs synchronized
异步I/O(aio)
I/O调度器
基本操作:合并、排序
Deadline
Anticipatory
CFQ
Noop(不排序)
排序:按绝对路径/inode/物理块
进程管理
execl
fork
COW:这些页被标记为只读,如果有进程试图修改,就会发生缺页中断
fork + exec => vfork:不要用。严格来讲,vfork是有bug的,考虑当exec调用失败,父进程将一直被挂起...
POSIX/C89 exit()
atexit
SIGCHLD
等待子进程终止
wait
waitpid
waitid*
BSD wait3 wait4(这里3,4指参数个数)
system
在执行command过程中,会阻塞SIGCHLD,同时SIGINT、SIGQUIT会被忽略
p153 利用fork()、exec系统调用和waitpid()实现system()是一个非常有用的练习
安全隐患*
用户和组*
{实际、有效、保留}用户ID/组ID(由于允许setuid/setgid,导致这里的复杂性,有没有更好一点的设计方法?)
会话和进程组(只在实现shell时需要了解吧?略)
守护进程
大致处理:pid=fork() --> setsid() --> chdir("/") --> chose(0..NR_OPEN) --> open("/dev/null", O_RDWR) --> dup(0);dup(0)
daemon(nochdir, noclose)
高级进程管理
CPU约束 vs I/O约束
CFS(根据权值,而非时间片)
sched_yield()
nice(人品值) -_-
更好的:get/setpriority
ioprio_get/set
sched_get/setaffinity
实时系统(这里讨论的内容似乎有点过多了)
延迟、抖动*、截止期限
实时调度策略(静态优先级,不受nice影响):SCHED_FIFO/RR/OTHER
资源现状(rlimit)*
线程
p205 coroutines和fibers(超出了本书的探讨范畴?k)
p212 锁住数据,而不是代码
Pthreads
LinuxThreads -> NPTL ( -> NGPT?)
pthread_setcancelstate/type, pthread_cancel
join(应该只有一个可以)和detach(使得不可join)
互斥*
文件和目录管理
stat/lstat/fstat
chmod/fchmod
chown/lchown/fchown
扩展属性xattr(略)
getcwd
chdir/fchdir
mkdir/rmdir/opendir/readdir/closedir/getdents
link(oldpath, newpath)
symlink
unlink
移动文件:rename
设备节点
/dev/null, /dev/zero, /dev/full
/dev/random, /dev/urandom
带外通信(ioctl)
inotify
p270 零长度数组(但是实际上导致内存分配了许多不同大小的块?)
内存管理
匿名内存映射(不会造成数据段碎片?)
glibc用来满足大的分配,临界值一般为128KB
p = mmap(NULL, 512*1024, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
mallopt*
$ MALLOC_CHECK=1 ./test
p300 不要使用alloca()分配的内存作为函数调用的参数
C99变长数组(VLAs):char buf[i];
内存操作
memset, bzero ==〉优先使用calloc?
memcmp
memmove:可安全处理内存区域重叠问题(memcpy不支持)
mlock*
乐观的分配策略(仅到实际写时才分配), OOM Killer
信号
p329 在信号中确保可重入的函数*
信号集*
sigprocmask
sigpending
sigsuspend
sigaction
时间(这里谈不上系统编程了,就是C库API)
typedef long time_t;
struct timeval { tv_sec; tv_usec; }
struct tm { ... }
time --> gettimeofday
附录A C语言的GCC扩展
__attribute__((noinline/pure/const/noreturn/...))
likely(x)/unlikely(x)
__builtin_return_address
case 1 ... 10:
附录B 参考书目
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment