OS线程模型
线程模型
-
N对1
内核线程 映射 用户进程, 用户进程里可以启多个线程 -
1对1
内核线程和用户线程 1对1 Linux采用这种方式 -
N对M
用户线程被抽象为更轻量的线程, 内核线程和轻量的线程对应
进程间的数据是隔离的,父子进程间存在写时拷贝, 只要明白进程间变量是隔离的即可.
管道是基于文件实现的, 内核分配页做缓冲区, 形成循环列表
有名管道也是基于文件实现.
pthread_join 是阻塞等待线程结束
信号是在软件层面对中断的模拟.
对用户空间占用较大的程序,如cache, 当发生coredump时, 我们可以通过信号的方式, 捕获出错的信号,打印出堆栈, 而不需要
core出整个用户空间. SIGSEGV 11信号 SIGABRT
本地UNIX套接字,不经过外设, 直接使用内存块拷贝
ftok 文件不能删,因为它用的是inode节点,产生key
共享内存比较高效,因为没有内存拷贝
共享内存的同步 -- 一般使用信号量,保护共享内存的数据
共享内存实现方式 -- 队列模式、页模式、哈希模式
共享内存 -- 访问使用偏移量 ,不要用指针
消息队列 -- 内核实现的--不用考虑同步和互斥
信号量 -- 同步原语
文件内存映射, 比共享内存 可靠性高, 把文件映射到进程内存空间中, 不好的地方是回写文件要消耗io, 请求量很大的时候,大量回写会导致性能很差.
文件和锁 文件锁
GNP 通用网络模型
epoll监听文件描述符的状态 利用管道基于文件实现的特性, 监听管道状态, 实现实时通知.
非递归锁 -- 重复加锁,会导致死锁
递归锁 -- 可重复加锁,需释放多次
读写锁 -- 读多写少
多线程模型 - LF 和 半同步半异步
半同步半异步 由于有队列,会引入压队列和出队列的拷贝消耗, 但是有利于框架化,解耦IO和业务逻辑.
LF 比较简单,但是IO和业务耦合.
加锁和解锁 一秒可以几十万次,锁最大的问题是锁的占用时间
能不加锁就不加锁
空间换时间 减小锁的粒度 考虑临界区
避免死锁
性能要求较高的场景下 -- 两个map存储数据,切换,形成无锁方案
多线程更适合计算频繁、通信频繁、组件化、交互式
多进程更稳定