1:内核态与用户态是操作系统的两种运行级别。内核态拥有最高权限,可以访问所有系统指令;用户态只能访问一部分指令。
2:可以通过系统调用主动进入内核态,也可以通过异常和设备中断被动进入内核态
系统调用的核心是其使用了操作系统为用户特别开放的一个中断来实现的,它是一种正常的异常,产生中断后,调用中断处理程序,调用system_call函数,完成操作系统内核态的调用。
1:进程的生成:程序执行时,操作系统将可执行文件复制到内存中,内核将程序读入内存,为其分配空间和PID以及其他所需要的资源,然后内核为进程保存PID以及相对应的状态信息,并且将进程放入运行队列中等待执行,有操作系统调度执行。
2:线程的生成:利用更小的粒度的执行单元来实现并发执行,可以减少进程切换的开销。所有线程共享进程的资源,如代码段、数据段。但每个线程由自己的局部变量需要栈来存储,线程由自己的独立资源如栈、寄存器。
3:协程是微线程,在子程序内部执行,可在子程序内部中断,转到别多子程序,适当的时候再返回,协程效率极高,因为不存在写变量冲突,不需要多线程锁机制。
2:进程一般分为三部分:代码段、数据段、堆栈段(fork完全复制数据段和堆栈段、代码段共享,因为代码段只读,不可修改。写时复制:创建时候不复制,等待需要修改再复制)
3:进程的状态:就绪、运行、阻塞
守护进程:守护进程是运行在后台的一种生存期长的特殊进程。它独立于控制终端,处理一些系统级别的任务。
孤儿进程:父进程已退出,子进程没有退出。会被init进程收集
僵尸进程:父进程未退出,子进程已退出,但是父进程未调用wait()或者waitpid()获取子进程状态
1:管道 无名管道pipe(半双工、父子进程通信) 命名管道FIFO(半双工、无亲缘关系通信)
2:消息队列 在系统内核中建立一个保存消息的队列,表现形式是消息链表
3:共享内存 映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,多个进程共同访问
4:信号量 本质上是一个计数器,用于多进程对共享数据对象的读取,主要用来保护共享资源
5:socket套接字
线程通信方式的本质就是解决线程同步的问题。
1:互斥锁
简单加锁控制对共享资源的访问,互斥锁就两种状态,即上锁和解锁。
2:信号量
信号量>=0时,可以访问,否则就阻塞。
3:条件变量
用来自动阻塞一个线程,知道有某个情况发生为止
4:读写锁
读写锁一次只允许一个线程写,但允许多个线程读,这样效率就比互斥锁高。
操作系统虚拟内存到无力内存的映射表,就被称为页表。
缺页异常:malloc和mmap函数在分配内存的时候只是建立了进程虚拟地址空间,并没有分配虚拟内存对应的物理内存。当进程访问这些没有建立映射关系的虚拟内存时就会出现缺页异常。
死锁的四个必要条件:
解决办法:
保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么 在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。
互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。
信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源 ,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。在用创建信号量时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数 就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目, 不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开时将当前可用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。