- linux内核锁有:原子锁,自旋锁和信号量
- 内核调度时机有自愿调度和非自愿调度,自愿调度表示调用exit,sleep函数什么的,非自愿表示时间片用完
- linux申请内存的方式有:malloc, calloc, realloc, kmalloc, vmalloc (kmalloc保证分配的内存在物理上是连续的,vmalloc保证的是在虚拟地址空间上的连续)
- 登录linux,首先启动/etc/profile,然后启动用户目录下的.bash_profile, .bash_login和.profile中的一个, 如果是.bash_profile的话还会执行bashrc; 每次启动shell终端的时候都会调用/etc/bashrc和~/.bashrc文件
file:加载, r:运行, c:继续, b[行号]:设置断点, d:删除断点, s:下一步, n:下一行, p:打印变量值, i:显示各类信息, q:退出
select, poll, epoll都是IO多路复用的机制,所谓的IO多路复用机制就是通过一种机制可以见识多个描述符,一旦某个描述符就绪能通过程序进行相应的读写操作。 select和poll的实现机制类似,只是描述fd集合的方式不一样,poll使用pollfd,select使用fd_set;epoll算是select和poll的加强版。 select有三个缺点:
- 每次调用select时需要将fd集合从用户态拷贝到内核态,开销大
- select每次判断就绪都需要在内核态遍历所有传递进来的的fd,造成开销大
- 支持的文件描述符少,默认为1024
epoll有epoll_create, epoll_ctl, epoll_wait可以避免select的缺点,描述如下:
- epoll会在使用epoll_ctl注册事件时将fd拷贝到内核态,可以避免缺点一
- epool在设备就绪时会将就绪的fd加入到就绪链表中,可以避免每次查询所有的fd
使用一个进程服务多个客户,通常与客户通信的套接字设置为非阻塞的,阻塞只发生在select()、poll()、epoll_wait()等系统调用上面。缺点是无法利用对称多处理器的优势;select的描述符集个数有限制;会进行大量的系统调用。
accept/fork 模型,每当有客户连线时产生一个新的进程为之服务,缺点是进程占用资源多,进程切换开销太大,进程信息共享麻烦。
accept/pthread_create模型,有新客户来时创建一个服务线程而不是服务进程。这解决了多进程服务的一些问题,比如它占用资源少,信息共享方便。但是麻烦在于线程仍有可能消耗光,线程切换也需要开销。
消息队列可用在应用中以执行多种功能,比如要求服务、交换信息或异步处理等。中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源. 下面为个人理解: 消息队列的实现可以转化为生产者-消费者模型,可以通过STL的dqueue + 信号量等实现,可以在消息中增加超时时间戳以应对请求过多的问题。
- **线程:**互斥锁,读写锁,条件变量,信号量
- **进程:**管道,有名管道,信号,信号量,消息队列,共享内存,套接字, "文件与记录锁"
进程切换需要切换虚拟空间、内核栈、cpu寄存器、内核空间的切换。
- 保存程序计数其以及其他寄存器。
- 更新当前处于“运行态”的进程的进程控制块,把进程状态改为相应状态,更新其他相关域
- 把被切换进程的进程控制块移到相关状态的队列
- 选择另外一个进程开始执行,把该进程进程控制块的状态改为“运行态”
- 恢复被选择进程的处理器在最近一次被切换出运行态时的上下文,比如载入程序计数器以及其他处理器的值
- 进程间切换伴随着两次模式切换(用户--内核,内核--用户)
线程分两种,用户级线程和内核级线程:
- 在用户级线程中,有关线程管理的所有工作都由应用程序完成,内核没有意识到线程的存在,用户级线程间切换时,只需要保存用户寄存器的内容,程序计数器,栈指针,不需要模式切换。在进程的某个线程执行系统调用时,不仅该线程被阻塞,该线程所在进程的所有线程都被阻塞,无法利用多处理器
- 在内核级线程中,有关线程的管理工作都是由内核完成的,应用程序部分没有线程管理的权限,内核级线程间切换时,除了保存上下文,还要进行模式切换。可以利用多处理器,线程阻塞不会导致进程阻塞
- 不同的父进程号(译者注:即子进程的父进程号与父进程的父进程号不同, 父进程号可由getppid函数得到)
- 自己的文件描述符和目录流的拷贝(译者注:目录流由opendir函数创建,因其为顺序读取,顾称“目录流”)
- 子进程不继承父进程的进程,正文(text), 数据和其它锁定内存(memory locks)(译者注:锁定内存指被锁定的虚拟内存页,锁定后,不允许内核将其在必要时换出(page out))
- 在tms结构中的系统时间(译者注:tms结构可由times函数获得,它保存四个数据用于记录进程使用中央处理器的时间,包括:用户时间,系统时间, 用户各子进程合计时间,系统各子进程合计时间)
- 资源使用(resource utilizations)设定为0
- 阻塞信号集初始化为空集(译者注:原文此处不明确,译文根据fork函数手册页稍做修改)
- 不继承由timer_create函数创建的计时器
- 不继承异步输入和输出
- Mutexes 操作要比 Critical Section 费时的多。
- Mutexes 可以跨进程使用,Critical Section 则只能在同一进程中使用。
- 等待一个 Mutex 时,你可以指定"结束等待"的时间长度,而 Critical Section 则不行。