共计 5885 个字符,预计需要花费 15 分钟才能阅读完成。
还在排版中
对文中很多定义不是很必定,心愿能有人斧正。
发问
问题 1.为什么复制一个大文件比复制很多小的文件快。
问题 2.从服务器上复制文件应用多线程还是多过程。
问题 3.那么严格意义上线程除了 TLS 以外没有公有变量?只有取得了指针,便能够对其余线程的数据进行批改。
问题 4.内核空间和用户空间都是虚拟内存的一部分?
问题 5.对于高并发的网络申请,多过程多线程可能都不能满足?对于 c 语言来说,又是什么状况?
问题 5.各种 IPC 应用场景,尽管搜寻了一些材料,但感觉非常全面,了解不深。
问题 6.应用 socket 麻烦的中央,头,协定,封装,配置老本?
问题 7.零拷贝是什么
问题 8.冲洗和敞开?
问题 9.默认 I / O 流
问题 10.signal 和 sigaction 的区别
其余的也心愿老师能过目一下,确认下我的了解没有谬误
CPU 密集型和 IO 密集型
因为 python GILd 的存在,python 多线程并不是并行而是并发,也就导致了 CPU 密集型工作效率的降落
IO 密集型因为期待而挂起的工夫很长,所以多线程也实用,并且创立线程,上下文切换耗费的资源都比过程小,所以速度更快。
因而,对于 python,cpu 密集型应用多过程,而 IO 密集型应用多线程
对于高并发的网络申请,多过程多线程可能都不能满足?对于 c 语言来说,又是什么状况?
对于一个聊天室利用,十个通信设施各开一个线程,对 cpu 累赘很大,这时候利用的就是 IO 多路复用 select,poll,epoll
顺带一提,对于 cpu 读写的累赘应用的是缓存和缓冲。
暂未理解 并发 nginx,apache,tomcat,
过程的切换 = 过程中线程的切换
暂未了解 应用 socket 麻烦的中央,头,协定,封装,配置老本?
暂未理解IPC,RPC,API 网关
第一章
文件和目录的区别?
在 linux 中,都是以文件形容的,他们的文件类型不同。
目录文件存储了目录下所有文件名和 inode 的映射关系。
把文件 rm 掉会产生什么?
1)应用 unlink 缩小链接数量,
2)如果链接数为 0 开释 inode,则数据块放到可用空间列表中;
3)删除目录中的目录项
https://blog.csdn.net/weixin_…
为什么同一个文件系统挪动文件很快?
因为只删除了目录中原地位的对应关系,在挪动后的地位加上了新的对应关系,没有对数据进行写解决。
不同文件系统应用的是 rm+cp
格式化?
inode-table 也是须要占用存储空间的。
第三章
缓冲和缓存
见我的文章 buffer and cache
https://segmentfault.com/a/11…
第七章
曾经遗记 fork 和 vfork
暂未了解 如何保留明码,将明码写入环境变量中
第十章
kill -9 init 会产生什么?
The only signals that can be sent to process ID 1, the init process, are those for which init has explicitly installed signal handlers. This is done to assure the system is not brought down accidentally.
依据上文,什么都不会产生, 因为 init 没有对 SIGTERM 建设 signal handler?
https://unix.stackexchange.co…
第十一章?
cpu 上下文切换分为过程上下文切换,线程上下文切换,中断上下文切换
过程和线程的异同点?
(1)
线程是调度的根本单位,而过程则是资源领有的根本单位
过程时零碎资源分配的最小单位
线程时 cpu 操作和调度的最小单位,实质是一组寄存器的状态,是操作系统对寄存器状态的形象
e.g. 过程就是一个人,线程就是这个人收到的一件事件,对于很多事件,一个人能够做多件事件,或者能够喊很多人每个人做一件事。
(2)
上下文切换老本 过程远大于线程
过程的上下文不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包含了内核堆栈、寄存器等内核空间的状态。
线程上下文切换线程部分存储 (TLS) , 栈和寄存器等
这两种上下文切换的解决都是通过操作系统内核来实现的。
内核的这种切换过程随同的最显著的性能损耗是将寄存器中的内容切换出。
(3)
过程中的线程共享地址空间,过程间的通信的代价远大于线程间的通信
得设立管道,共享队列,信号,信号量,socket
(4)
线程的创立老本远远低于过程,因为线程中蕴含的数据量少于过程,线程只须要执行相干的数据即可,如,pc, 寄存器,栈,执行状态
第十一章
线程之间独有的资源有
https://cloud.tencent.com/dev…
栈区
同时函数运行时须要额定的寄存器来保留一些信息,像局部局部变量之类,这些寄存器也是线程公有的,一个线程不可能拜访到另一个线程的这类寄存器信息。
所属线程的栈区、程序计数器、栈指针以及函数运行应用的寄存器是线程公有的。这些信息有一个对立的名字,就是线程上下文,thread context。
那么严格意义上线程除了 TLS 以外没有公有变量?只有取得了指针,便能够对其余线程的数据进行批改。
TLS -> Thread Local Storge?
寄存在该区域中的变量是全局变量,所有线程都能够拜访
他是全局的,然而每个线程在拜访的时候都会存储一份成为本人的局部变量,批改就不会相互影响了
尽管看上去所有线程拜访的都是同一个变量,但该全局变量独属于一个线程,一个线程对此变量的批改对其余线程不可见。
实现原理相似有一个全局的词典,词典的 key 是线程 id,value 就是共享的全局变量的正本。
http://blog.hacksmeta.com/201…
线程共享的资源
代码区 编译后的代码
数据区 全局变量,动态变量。
堆区 C/C++ 中用 malloc 或者 new 进去的数据就寄存在这个区域,只有晓得指针,任何一个线程都能够拜访指针指向的数据,因而堆区也是线程共享的属于过程的资源。
栈区 如果一个线程能拿到来自另一个线程栈帧上的指针,那么该线程就能够扭转另一个线程的栈区,也就是说这些线程能够任意批改本属于另一个线程栈区中的变量。
动态链接库 动静链接的局部生成的库就是咱们相熟的动态链接库,在 Windows 下是以 DLL 结尾的文件,在 Linux 下是以 so 结尾的文件。
文件
如果程序在运行过程中关上了一些 文件,那么过程地址空间中还保留有关上的文件信息,过程关上的文件也能够被所有的线程应用,这也属于线程间的共享资源。
遗记问题是什么 cpu 密集型中升高 cpu 使用率?
①减少 cpu
②升高零碎过程,线程数
锁的应用场景
见我的文章 UNIX 环境高级编程第十一章遗留问题笔记
https://segmentfault.com/a/11…
第十四章
阻塞,非阻塞
阻塞和非阻塞关注的是程序在期待调用后果(音讯,返回值)时的状态.
阻塞调用是指调用后果返回之前,以后线程会被挂起。调用线程只有在失去后果之后才会返回。
非阻塞调用指在不能立即失去后果之前,该调用不会阻塞以后线程。程序定时?查看调用是否实现。
同步和异步
同步与异步同步和异步关注的是音讯通信机制 (synchronous communication/ asynchronous communication).
所谓同步,就是在收回一个 调用 时,在没有失去后果之前,该 调用 就不返回。然而一旦调用返回,就失去返回值了。换句话说,就是由 调用者 被动期待这个 调用 的后果。而异步则是相同,调用 在收回之后,这个调用就间接返回了,所以没有返回后果。换句话说,当一个异步过程调用收回后,调用者不会立即失去后果。而是在 调用 收回后,被调用者 通过状态、告诉来告诉调用者,或通过回调函数解决这个调用。
第十五章
https://www.jianshu.com/p/498…
过程间通信有什么类型?他们的利用场景别离是什么?
内核空间和用户空间都是虚拟内存的一部分?
音讯队列和管道基本上都是 4 次拷贝,而共享内存(mmap, shmget)只有两次。
一、管道
它是半双工的(即数据只能在一个方向上流动),具备固定的读端和写端。
它只能用于具备亲缘关系的过程之间的通信(也是父子过程或者兄弟过程之间)。
它能够看成是一种非凡的文件,对于它的读写也能够应用一般的 read、write 等函数。然而它不是一般的文件,并不属于其余任何文件系统,并且只存在于内存中。
利用场景?
二、FIFO
FIFO,也称为命名管道,它是一种文件类型。
FIFO 能够在无关的过程之间替换数据,与无名管道不同。
FIFO 有路径名与之相关联,它以一种非凡设施文件模式存在于文件系统中。
利用场景?
三、音讯队列
音讯队列,是音讯的链接表,寄存在内核中。一个音讯队列由一个标识符(即队列 ID)来标识。
音讯队列是面向记录的,其中的音讯具备特定的格局以及特定的优先级。
音讯队列独立于发送与接管过程。过程终止时,音讯队列及其内容并不会被删除。
音讯队列能够实现音讯的随机查问, 音讯不肯定要以先进先出的秩序读取, 也能够按音讯的类型读取。
利用场景
长处下面曾经说了,就是在非凡场景下有其对应的益处,解耦、异步、削峰
零碎可用性升高:零碎引入的内部依赖越多,越容易挂掉,原本你就是 A 零碎调用 BCD 三个零碎的接口就好了,人 ABCD 四个零碎好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整?MQ 挂了,整套零碎解体了,你不就完了么。
零碎复杂性进步:硬生生加个 MQ 进来,你怎么保障音讯没有反复生产?怎么解决音讯失落的状况?怎么保障消息传递的程序性?头大头大,问题一大堆,苦楚不已
一致性问题:A 零碎解决完了间接返回胜利了,人都认为你这个申请就胜利了;然而问题是,要是 BCD 三个零碎那里,BD 两个零碎写库胜利了,后果 C 零碎写库失败了,咋整?你这数据就不统一了。
https://zhuanlan.zhihu.com/p/…
音讯队列和管道基本上都是 4 次拷贝,而共享内存(mmap, shmget)只有两次。
第一步读磁盘文件是要通过一次零碎调用的,它首先将文件内容从磁盘拷贝到内核空间的一个缓冲区,而后再将这些数据拷贝到用户空间,实际上是两次数据拷贝。第三步回写也一样也要通过两次数据拷贝。
4 次:1,write()输出从磁盘到 A 内核空间。2,写进 B 用户空间。3,B 调用 read()读入内核空间。4,从内核空间中放入磁盘.
而内存映射文件是操作系统的提供的一种机制,能够缩小这种不必要的数据拷贝,从而提高效率。它由 mmap()将文件间接映射到用户空间,mmap()并没有进行数据拷贝,真正的数据拷贝是在缺页中断解决时进行的,因为 mmap()将文件间接映射到用户空间,所以中断处理函数依据这个映射关系,间接将文件从硬盘拷贝到用户空间,所以只进行了一次数据拷贝,比 read 进行两次数据拷贝要好上一倍,因而,内存映射的效率要比 read/write 效率高。
2 次:1,输出到用户空间。2,用户空间到输入。
零拷贝?
音讯队列和管道都是内核对象,所执行的操作也都是零碎调用,而这些数据最终是要存储在内存中执行的。因而不可避免的要通过 4 次数据的拷贝。然而共享内存不同,当执行 mmap 或者 shmget 时,会在内存中开拓空间,而后再将这块空间映射到用户过程的虚拟地址空间中,即返回值为一个指向一个内存地址的指针。当用户应用这个指针时,例如赋值操作,会引起一个从虚拟地址到物理地址的转化,会将数据间接写入对应的物理内存中,省去了拷贝到内核中的过程。当读取数据时,也是相似的过程,因而总共有两次数据拷贝。
长处:
A. 咱们能够通过发送音讯来简直完全避免命名管道的同步和阻塞问题。B. 咱们能够用一些办法来提前查看紧急音讯。
毛病:
A. 与管道一样,每个数据块有一个最大长度的限度。B. 零碎中所有队列所蕴含的全副数据块的总长度也有一个下限。
四、信号量
信号量(semaphore)与曾经介绍过的 IPC 构造不同,它是一个计数器。信号量用于实现过程间的互斥与同步,而不是用于存储过程间通信数据。
信号量用于过程间同步,若要在过程间传递数据须要联合共享内存。
信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。
每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且能够加减任意正整数。
反对信号量组。
信号量的双用处:互斥 相似于 mutex,然而 mutex 只能是加锁的人解锁 与 同步 -> 线程 1 和线程 2 -> 线程 3
五、共享内存
共享内存(Shared Memory),指两个或多个过程共享一个给定的存储区。
共享内存是最快的一种 IPC,因为过程是间接对内存进行存取。
因为多个过程能够同时操作,所以须要进行同步。
信号量 + 共享内存通常联合在一起应用,信号量用来同步对共享内存的拜访。
应用场景
传递很大的数据
大量读同一数据的场景
六、信号
应用场景
接管过程某个工夫曾经产生,死亡。
七、套接字
应用场景
八、unix 域套接字
应用场景
Linux- 过程间通信(N): 各种 IPC 的应用场景
- 管道:只能用于具备亲缘关系的进行通信,应用面绝对较窄,理论开发中较少应用;
- FIFO(命名管道):能够用于任意过程间的通信,对于大块数据的传输效率较高,可利用于单过程大量数据传递,和多个过程向一个过程传递数据;
- 信号:无奈传递数据,而且信号的品种无限,只实用于实现一些简略的事件告诉工作,如配置跟新信号告诉,一个服务通过信号告知另一个服务本身状态;
- 文件锁:不能用来传递数据,用来对操作进行协调,利用文件锁实现多个过程对于某个资源的排队申请,或者多个过程对系统某个全局资源进行读写操作,能够通过文件锁实现过程间读写锁的性能;
XSI IPC:
- 共享内存:最为高效的过程间通信形式,过程能够间接读写内存,不须要任何数据拷贝,实用于多个过程共享数据,或过程间频繁的进行大量的数据交互;– 倡议应用 mmap 形式;
- 音讯队列:过程间传递简略的命令和管制音讯,如配置更新告诉,多过程对多过程的通信等,能够简化代码逻辑;– 倡议应用全双工管道代替;
- 信号量:某种资源数为 N,多个过程都在应用该资源,为了进行过程间的互斥,能够应用初始值为 N 的信号量;– 倡议应用记录锁代替;
套接字 IPC:
- unix 域套接字:某个服务与多个服务同时通信,此时须要保护多个通信通道,应用 unix 套接字,能够应用 linux IO 多路复用性能;– 倡议优先思考网络套接字;
- 网络套接字:如果零碎须要反对分布式部署,服务可能在同一设施或者不同设施,此时应用网络套接字比拟适合,进步了扩展性;
第十六章
实现一个多客户端单服务端的聊天室利用。
见我的文章多人聊天室(多线程 ||epoll)
https://segmentfault.com/a/11…