標籤:linux c posix 系統編程 gcc epoll
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 參考書目
Linux系統編程(第2版)筆記 (本書基本上就是Linux C API的簡單使用說明,入門層級的)