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

  1. read(): EINTR EAGAIN
    1. 其他错误:EBADF EFAULT EINVAL EIO
  2. Append模式:每次write之前的文件位置更新是原子操作
  3. 延迟写:/proc/sys/vm/dirty_expire_centisecs
  4. O_DIRECT:长度、偏移均应是底层设备扇区(一般4KB)的整数倍
  5. lseek --> pread/pwrite:避免了多个线程操作同一个fd时的竞争
  6. p51 select()和poll()都是水平触发,不是边缘触发
  7. poll() vs select()
    1. 对值较大的文件描述符,后者要检查集合中的每个位,而前者只是个链表(但是复杂的数据结构怎么传递进内核的?)
    2. select()返回时重新创建fd_set,而poll()会把events和revents分开
  8. VFS、页缓冲、页回写

缓冲I/O

  1. p72 ungetc:只要有足够的内存,Linux允许无限次放回
  2. p72 rewind(stream) => fseek(stream, 0, SEEK_SET)且清空错误
  3. p80 fflush()只是把用户缓冲数据写入内核缓冲,不保证最终写到物理介质上(fsync)
  4. setvbuf:_IO{N,L,F}BUF 无缓冲/行缓冲/块缓冲
  5. flockfile:允许递归加锁?

高级文件I/O

  1. 向量I/O?:readv/writev
  2. epoll(Linux专有?)
    1. epoll_create1
    2. epoll_ctl(epfd, op, fd, event) <-- 这个API看上去够复杂的了
      1. event->events |= EPOLLET; 边缘触发?(非阻塞I/O,需要仔细检查EAGAIN?)
    3. epoll_wait
  3. mmap
    1. long page_size = sysconf( _SC_PAGESIZE ); //或getpagesize()、直接PAGE_SIZE
    2. p109 库函数如glibc,经常使用mremap()来实现高效的realloc()
    3. POSIX.1 mprotect() 要么只读,要么只写,要么可执行,不能同时
    4. madvise():准确预读?(除非是POSIX_FADV_RANDOM)
  4. synchronnous vs synchronized
    1. 异步I/O(aio)
  5. I/O调度器
    1. 基本操作:合并、排序
    2. Deadline
    3. Anticipatory
    4. CFQ
    5. Noop(不排序)
    6. 排序:按绝对路径/inode/物理块

进程管理

  1. execl
  2. fork
    1. COW:这些页被标记为只读,如果有进程试图修改,就会发生缺页中断
  3. fork + exec => vfork:不要用。严格来讲,vfork是有bug的,考虑当exec调用失败,父进程将一直被挂起...
  4. POSIX/C89 exit()
    1. atexit
    2. SIGCHLD
  5. 等待子进程终止
    1. wait
    2. waitpid
    3. waitid*
    4. BSD wait3 wait4(这里3,4指参数个数)
    5. system
      1. 在执行command过程中,会阻塞SIGCHLD,同时SIGINT、SIGQUIT会被忽略
      2. p153 利用fork()、exec系统调用和waitpid()实现system()是一个非常有用的练习
      3. 安全隐患*
  6. 用户和组*
    1. {实际、有效、保留}用户ID/组ID(由于允许setuid/setgid,导致这里的复杂性,有没有更好一点的设计方法?)
  7. 会话和进程组(只在实现shell时需要了解吧?略)
  8. 守护进程
    1. 大致处理:pid=fork() --> setsid() --> chdir("/") --> chose(0..NR_OPEN) --> open("/dev/null", O_RDWR) --> dup(0);dup(0)
    2. daemon(nochdir, noclose)

高级进程管理

  1. CPU约束 vs I/O约束
  2. CFS(根据权值,而非时间片)
  3. sched_yield()
  4. nice(人品值) -_-
    1. 更好的:get/setpriority
    2. ioprio_get/set
  5. sched_get/setaffinity
  6. 实时系统(这里讨论的内容似乎有点过多了)
    1. 延迟、抖动*、截止期限
    2. 实时调度策略(静态优先级,不受nice影响):SCHED_FIFO/RR/OTHER
  7. 资源现状(rlimit)*

线程

  1. p205 coroutines和fibers(超出了本书的探讨范畴?k)
  2. p212 锁住数据,而不是代码
  3. Pthreads
    1. LinuxThreads -> NPTL ( -> NGPT?)
    2. pthread_setcancelstate/type, pthread_cancel
    3. join(应该只有一个可以)和detach(使得不可join)
    4. 互斥*

文件和目录管理

  1. stat/lstat/fstat
  2. chmod/fchmod
  3. chown/lchown/fchown
  4. 扩展属性xattr(略)
  5. getcwd
  6. chdir/fchdir
  7. mkdir/rmdir/opendir/readdir/closedir/getdents
  8. link(oldpath, newpath)
  9. symlink
  10. unlink
  11. 移动文件:rename
  12. 设备节点
    1. /dev/null, /dev/zero, /dev/full
    2. /dev/random, /dev/urandom
  13. 带外通信(ioctl)
  14. inotify
    1. p270 零长度数组(但是实际上导致内存分配了许多不同大小的块?)

内存管理

  1. 匿名内存映射(不会造成数据段碎片?)
    1. glibc用来满足大的分配,临界值一般为128KB
    2. p = mmap(NULL, 512*1024, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
  2. mallopt*
    1. $ MALLOC_CHECK=1 ./test
  3. p300 不要使用alloca()分配的内存作为函数调用的参数
    1. C99变长数组(VLAs):char buf[i];
  4. 内存操作
    1. memset, bzero ==〉优先使用calloc?
    2. memcmp
    3. memmove:可安全处理内存区域重叠问题(memcpy不支持)
  5. mlock*
  6. 乐观的分配策略(仅到实际写时才分配), OOM Killer

信号

  1. p329 在信号中确保可重入的函数*
  2. 信号集*
    1. sigprocmask
    2. sigpending
    3. sigsuspend
    4. sigaction

时间(这里谈不上系统编程了,就是C库API)

  1. typedef long time_t;
  2. struct timeval { tv_sec; tv_usec; }
  3. struct tm { ... }
  4. time --> gettimeofday

附录A C语言的GCC扩展

  1. __attribute__((noinline/pure/const/noreturn/...))
  2. likely(x)/unlikely(x)
  3. __builtin_return_address
  4. case 1 ... 10:

附录B 参考书目 

你可能感兴趣的:(c,linux,gcc,epoll,posix,系统编程)