Linux系统编程(第2版)笔记 (本书基本上就是Linux C API的简单使用说明,入门级别的)

Linux系统编程(第2版)

跳转至: 导航搜索

目录

入门和基本概念

文件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 参考书目

时间: 2024-08-08 13:45:13

Linux系统编程(第2版)笔记 (本书基本上就是Linux C API的简单使用说明,入门级别的)的相关文章

《Linux系统编程》第二章笔记(一)

文件I/O 前言 文件概念对于Linux系统的重要性不言而喻,本章主要介绍了内核为文件的创建.读.写.定位等系统调用以及高效的I/O机制.Linux系统为文件操作提供了通用的系列系统调用,使开发人员能够对所有"文件"做相同的操作,同时还提供了ioctl()系统调用对非通用文件操作,fcntl()系统调用对文件描述符做操作. 此外Linux内核为了弥补CPU运算速度和磁盘I/O速度的巨大差异,引入了页缓存.页回写机制.简单来说就是读取文件时多读取一部分并保存在内核缓冲区中,在下次收到读取

《Linux系统编程手册》读书笔记——第2章基本概念

操作系统的核心--内核 内核的职责 进程调度:Linux属于抢占式多任务操作系统,多个进程可同时驻留于内存,且每个进程都能获得对CPU的使用权.哪些进程获得对CPU的使用,以及每个进程能使用多长时间 ,都由内核进程调度程序决定. 内存管理:Linux采用了虚拟内在管理机制. 提供了文件系统 创建和终止进程:内核可将新程序载入内存,为其提供运行所需的资源.一旦程序执行完毕,内核还要确保释放其占用资源,以供后续程度重新使用. 对设备的访问:内核既为程序访问设备提供了简化版的标准接口,同时还要仲裁多个

嵌入式 Linux系统编程(六)——系统信息

嵌入式 Linux系统编程(六)--系统信息 一.时间 Linux系统下常用的时间类型:time_t.struct tm.struct timeval.struct timespec. 1.time_t类型时间 time_t实际是一个长整型.其值表示为从UTC(coordinated universal time)时间1970年1月1日00时00分00秒(也称为Linux系统的Epoch时间)到当前时刻的秒数.由于time_t类型长度的限制,它所表示的时间不能晚于2038年1月19日03时14分

Linux系统编程笔记

写在开篇:出于对未来职业规划的考虑(其实还是一团糟),制定了一个基本的学习方向,那就是从系统编程学习API慢慢的深入内核,这是一个比较成熟的学习路线.所以从本篇开始,在这段时间会陆续记录Linux系统编程的学习笔记,除了供学习之余复习只用,同时也期望能记录初入职场摸爬滚打的第一个3年. 第一章 文件I/O 文件访问的基本调用一般是 read()和write(),但是在访问文件之前,要做的是一项很重要的工作就是:打开,没错!通过调用 open()或create()实现 #include <sys/

《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

<Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h>文件中的常量. 通过cat 命令查看: [email protected]:~/Code/tlpi$ cat /usr/include/limits.h /* Copyright (C) 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2005 Free Software

《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

<Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候都会发生缓冲.通过缓冲可以在一定程度上将用户空间与实际的物理设备分离,还可以减少内核访问磁盘的次数. 先来看看关于内核缓冲区高速缓冲:read和write调用在对磁盘文件进行操作的时候不会直接访问磁盘,如下图所示. 例如:write(fd, "abc", 3) write调用会将"

《Linux/Unix系统编程手册》读书笔记9(文件属性)

<Linux/Unix系统编程手册>读书笔记 目录 在Linux里,万物皆文件.所以文件系统在Linux系统占有重要的地位.本文主要介绍的是文件的属性,只是稍微提及一下文件系统,日后如果有更深入的研究一定会写出来. 下图为磁盘分区与文件系统的关系 文件系统中的文件(目录)在i-node表上都有唯一的记录(i-node).i-node通过数据块指针指向数据块,这些数据块就是该i-node对应的文件的数据. i-node与数据块的关系如下: 因为Linux支持很多类型的文件系统,但是每种文件系统的

Linux系统编程博客参考

通过看前人的博客更易于把握知识要点 http://www.cnblogs.com/mickole/category/496206.html <Linux系统编程> http://www.cnblogs.com/DayByDay/category/599079.html <UNIX环境高级编程学习笔记> http://blog.csdn.net/bytxl/article/details/8584993 UNIX环境高级编程(第2版)- 第1-10章

LINUX系统编程 由REDIS的持久化机制联想到的子进程退出的相关问题

19:22:01 2014-08-27 引言: 以前对wait waitpid 以及exit这几个函数只是大致上了解,但是看REDIS的AOF和RDB 2种持久化时 均要处理子进程运行完成退出和父进程需要做的什么事情,所以特定看了UNIX环境编程和LINUX系统编程这2本书 重新梳理下整个要点. 内容: 一般而言: 如果程序类似于下面的情况: if((pid=fork())==0) { dochildtthing(); exit(0); } else if(pid>0) { dofathertt