update srv mod

This commit is contained in:
lemonchann
2020-07-06 00:34:09 +08:00
parent b85eeac5dc
commit 40b10d260a
27 changed files with 74 additions and 177 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -1 +1 @@
<mxfile host="Electron" modified="2020-07-03T06:25:57.666Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.3.5 Chrome/83.0.4103.119 Electron/9.0.5 Safari/537.36" etag="F8Pf7yZE7unJVLCwhuWF" version="13.3.5" type="device"><diagram id="jHw1jEoRDi-KdsNDSuBp" name="Page-1">7ZzRcqM2FIafRpfZAQkJuDSJ03Z2Ou1Opu3eEiPbTLHxYhwnffoKgzBIEMAbhL2rq8QHST4cPklHv4QBut+8/pL4u/XvcUAjAI3gFaAHAKFpOIT9ySxvucUlhWGVhEFR6Gx4Cv+jvGZhPYQB3dcKpnEcpeGublzE2y1dpDWbnyTxsV5sGUf1b935KyoZnhZ+JFv/CYN0nVsdaJ/tv9JwtebfbBI3v7LxeeHiTvZrP4iPFROaA3SfxHGa/7d5vadRFjwel7zeY8vV0rGEbtM+Fb4c/v7yx53z1/Lr4vjbW3CPntPPd0UrL350KG64cDZ94xFYHJIXmrVhAuTRbTDLoso+LiJ/vw8XzLhON1FxfZ8m8b/0Po7i5FQbGYb9+Mhc8vJ2aSCF++y/WUaF4UTjDU2TN1bkeI47LmK5roSc2xIa+Wn4Um/eLx7/qmyu/IY/45B9MTQ4qnbRTgEqEpvYx4dkQYta1TgLDZXoFg2VDvKGUj9Z0VRqiMXVf6sU22UF9u0Ol2AJDrf5Jd4gtGvl2T+5B/xT5RmcTSemBvAFNV8tWCBofMIXEoaFJ2m5YlMfxRhpc7o3/bZQYxzOkOasBY7v4cxVxRkL71DOxD6ghjOrm7MkPmyDErTjOkzp085fZFePLEfqy9kyjCJu38ZbWhbmaQgsYXyhSUpfh+LIKyAhkHxaqeBqwQZeTVeY16psVp7C8CDjhiCTKM2CEp8YWJTxIt8OWf7k5ZFbLpdVE1kVf0919zt/W3tSvGDW6N3+lHnOWAGT7F7bW3kuDXMMWHLrYDAnYGYAzwFzG8xc4M3A3AWuDTyLV2JReBYbYrbcI8mc3yQ3C3SxB53WEUoo891/PhUw2Gf/kMb53Zwu+1G42mbDHOOBsqB5GS0hS3BnxYVNGARZZa/opOxrsAfww3sMCsYz8sbHQIkMXB8PbBlKp4FJOBaSpLvfs1bYooTeRJ8XB09k8YG9EuAyYaz1+vdmpO8Ksd3V67t7rlXvuZeNE5Ue7gDvEbjeqWM7wGE9+/0OrXtuQ5rrSmA1ZT+j9VxHZ4Z8UHXER0MuzQwtKK5x8UiZoYXanG7zTbxNaBMVmaGrOWuBgz2yCykjEmXjMCZJP2QY/Xat/Dh88XFVAyZxcTFg2FADGJYmxQ7ARPCVANZDC76hHBeJMbTkJYTiDNeEDRG+shTX0yluF1nS/Na4elKa5JpN+ufEZNmZEsLg4mRpsAYvyx15yLKUYtUkd2qsbg0rUcafHKtOgVdjdf1YQXHjYHKsmkRajdWNYSXl7Y6cW6nF6gqFaY3V4KRdXOpPjlWTMK2xujWsrGvDSuvQbQfeiHGhTCjuaWE00mkr2Oxw3xN9GCuQCbmPGjCJC2JIu2CXHunDZ01p5CN9Z6d744+xig012EOP/llAwx8HmqsKNPFMXw/QxE6gCLQmWV4A7dYO9QkzieU6n+yGzETtuT7YqVJfx8E+G7hWlgDPCXAc4Nn6YN9oB/sIlqlUerAP9jjRe0O7nuIWAjbd6U/2wRvQe/XRvk62pHSXbw9NtesJOwXfcecTq+d8goHzAJzesoqePXqPbmRitQVeoTY8kDaNlbRBOj1WV6gNa6wGz5fo2rBq0oYvmS+NPX9Pn9vMdxm6eG0mU8csrge8eXZybcaMSHPYyaEwvFkNSoDSNRfvF1rZk3a7iXHpGxmGpOvVG/qos/Ky5v2uX+INYqzibXAtHbdxQQxJ7+2NmCUihsZ66UfSu60O6VjCH1tKfnagh3T8s4BmfRxojjLQ3MGgiZ1AEWg9fuDihmRKJEbRdKaXKVGTFHxlMqVednWyJc14/OWIqWRK1Cl/a5nyhyJQGt2ILJQrXfijKzwZrfWkwViJadHkWGn1+wfASnydcUSs2Mfz713mqfH5V0PR/H8=</diagram></mxfile> <mxfile host="Electron" modified="2020-07-05T16:32:56.739Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.3.5 Chrome/83.0.4103.119 Electron/9.0.5 Safari/537.36" etag="KryluacAKJk9wgiBn-e7" version="13.3.5" type="device"><diagram id="jHw1jEoRDi-KdsNDSuBp" name="Page-1">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</diagram></mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -1,4 +1,6 @@
高频面试知识点总结:面试官问我高并发服务模型哪家强? 面试中经常会被问到高性能服务模型选择对比,以及如何提高服务性能和处理能力,这其中涉及操作系统软件和计算机硬件知识,其实都是在考察面试者的基础知识掌握程度,但如果没准备的话容易一头雾水,这次带大家从头到尾学习一遍,学完这一篇再也不怕面试官刨根问底了!
## 任务类型 ## 任务类型
@@ -12,6 +14,7 @@
CPU 密集型任务虽然也可以用多任务完成但是任务越多任务之间切换的时间就越多CPU 执行效率反而更低,所以要最高效地利用 CPU任务并行数应当等于 CPU 的核心数,避免任务在 CPU 核之间频繁切换。 CPU 密集型任务虽然也可以用多任务完成但是任务越多任务之间切换的时间就越多CPU 执行效率反而更低,所以要最高效地利用 CPU任务并行数应当等于 CPU 的核心数,避免任务在 CPU 核之间频繁切换。
![芯片线路](https://upload-images.jianshu.io/upload_images/7842464-fa3f105f2afd7764.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### IO密集型任务 ### IO密集型任务
@@ -20,13 +23,16 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
对于 IO 密集型任务,任务越多 CPU 效率越高,但也不是无限的开启多任务,如果任务过多频繁切换的开销也不可忽视。常见的大部分程序都是执行 IO 密集型任务,比如互联网业务的 Web 服务,数据库操作等。 对于 IO 密集型任务,任务越多 CPU 效率越高,但也不是无限的开启多任务,如果任务过多频繁切换的开销也不可忽视。常见的大部分程序都是执行 IO 密集型任务,比如互联网业务的 Web 服务,数据库操作等。
![五彩的以太网口](https://upload-images.jianshu.io/upload_images/7842464-3ccf6820d249dffb.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 服务模型 ## 服务模型
不管是 CPU 密集型任务还是 IO 密集型任务,提高服务器处理能力,可以从软件和硬件两个层面来做文章。 不管是 CPU 密集型任务还是 IO 密集型任务,**要提高服务器处理能力,可以从软件和硬件两个层面来做文章。**
先说软件层面,单个任务处理能力有限,可以通过启动多个功能完全相同的服务实例,借此来提高服务整体处理性能,多服务实例的实现主流的技术有三种:多进程、多线程、多协程。 先说软件层面,单个任务处理能力有限,可以通过启动多个功能完全相同的服务实例,借此来提高服务整体处理性能,多服务实例的实现主流的技术有三种:**多进程、多线程、多协程**。当然除了用多实例的方式,还有 IO 多路复用、异步 IO 等技术,为了文章主题明确,不在本文展开讨论
@@ -34,11 +40,11 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
既然有三种技术实现,那么你可能会问,在三个模型里选一个最好的来实现服务,该如何选择一个适合的服务模型呢? 既然有三种技术实现,那么你可能会问,在三个模型里选一个最好的来实现服务,该如何选择一个适合的服务模型呢?
![我全都要 - 《九品芝麻官》徐锦江 周星驰我全都要_我全都要_影视表情表情](http://wx4.sinaimg.cn/large/6e3e5b9bly1ftfloyx9ygg206y06yhd9.gif) ![](http://wx4.sinaimg.cn/large/6e3e5b9bly1ftfloyx9ygg206y06yhd9.gif)
抱歉,小孩子才做选择我全都要!哈哈,开个玩笑。 抱歉,小孩子才做选择我全都要!哈哈,开个玩笑。
答案是没有最好服务模型选择要结合自身服务处理的**任务类型**任务类型就是我们上面说的 CPU 密集型和 IO 密集型,只有清楚的知道所处理业务的任务类型,才能在上述服务模型中选择其一或多种模型组合,来搭建适合你的高性能服务框架。 答案是没有最好**服务模型选择要结合自身服务处理的任务类型**任务类型就是我们上面说的 CPU 密集型和 IO 密集型,只有清楚的知道所处理业务的任务类型,才能在上述服务模型中选择其一或多种模型组合,来搭建适合你的高性能服务框架。
@@ -52,9 +58,9 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
### 多进程模型 ### 多进程模型
多进程模型是启动多个服务进程。原来由一个进程做的事,当一个进程忙不过来,创建几个功能一样的进程来帮它一起干活,人多力量大。 多进程模型是启动多个服务进程。原来由一个进程做的事,当一个进程忙不过来,创建几个功能一样的进程来帮它一起干活,人多力量大。
由于多进程地址空间不同,数据不能共享,一个进程内创建的变量在另一个进程是无法访问。操作系统看不下去了,凭什么同在一台机器,彼此相爱的两个进程不能说说话呢? **由于多进程地址空间不同,数据不能共享,一个进程内创建的变量在另一个进程是无法访问**。操作系统看不下去了,凭什么同在一台机器,彼此相爱的两个进程不能说说话呢?
于是操作系统提供了各种系统调用,搭建起各个进程间通信的桥梁,这些方法统称为进程间通信 IPC (`IPC InterProcess Communication`) 于是操作系统提供了各种系统调用,搭建起各个进程间通信的桥梁,这些方法统称为进程间通信 IPC (`IPC InterProcess Communication`)
@@ -76,7 +82,8 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
4. 空的缓冲区有新数据写入,或者满的缓冲区有数据读出时,唤醒等待队列中的进程继续读写。 4. 空的缓冲区有新数据写入,或者满的缓冲区有数据读出时,唤醒等待队列中的进程继续读写。
![img](https://upload-images.jianshu.io/upload_images/1281379-05378521a7b41af4.png?imageMogr2/auto-orient/strip|imageView2/2/format/webp) ![管道图解](https://upload-images.jianshu.io/upload_images/7842464-39bdc35e79491189.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
@@ -85,8 +92,7 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
上面介绍的管道也称为匿名管道,只能用于亲缘关系的进程间通信。为了克服这个缺点,出现了有名管道 FIFO 。有名管道提供了一个路径名与之关联,以文件形式存在于文件系统中,这样即使不存在亲缘关系的进程,只要可以访问该路径也能相互通信。 上面介绍的管道也称为匿名管道,只能用于亲缘关系的进程间通信。为了克服这个缺点,出现了有名管道 FIFO 。有名管道提供了一个路径名与之关联,以文件形式存在于文件系统中,这样即使不存在亲缘关系的进程,只要可以访问该路径也能相互通信。
命名管道支持同一台计算机的不同进程之间,可靠的、单向或双向的数据通信。 命名管道支持同一台计算机的不同进程之间,可靠的、单向或双向的数据通信。
![FIFO图解.png](https://upload-images.jianshu.io/upload_images/7842464-5a23ebc5a22dce10.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![img](https://upload-images.jianshu.io/upload_images/5709266-4eca614f99ac711b.png?imageMogr2/auto-orient/strip|imageView2/2/w/625/format/webp)
@@ -101,8 +107,6 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
- 硬件来源:用户按键输入`Ctrl+C`退出、硬件异常如无效的存储访问等。 - 硬件来源:用户按键输入`Ctrl+C`退出、硬件异常如无效的存储访问等。
- 软件终止:终止进程信号、其他进程调用 kill 函数、软件异常产生信号。 - 软件终止:终止进程信号、其他进程调用 kill 函数、软件异常产生信号。
![img](https://upload-images.jianshu.io/upload_images/5709266-bc52bfc7a89dfee4.png?imageMogr2/auto-orient/strip|imageView2/2/w/790/format/webp)
#### 消息队列 Message Queue #### 消息队列 Message Queue
@@ -110,8 +114,8 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
消息队列是存放在内核中的消息链表,每个消息队列由消息队列标识符表示, 只有在内核重启或主动删除时,该消息队列才会被删除。 消息队列是存放在内核中的消息链表,每个消息队列由消息队列标识符表示, 只有在内核重启或主动删除时,该消息队列才会被删除。
消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 另外,某个进程往一个消息队列写入消息之前,并不需要另外读进程在该队列上等待消息的到达。 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 另外,某个进程往一个消息队列写入消息之前,并不需要另外读进程在该队列上等待消息的到达。
![消息队列图解](https://upload-images.jianshu.io/upload_images/7842464-6bbd3c9658da6116.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![img](https://upload-images.jianshu.io/upload_images/5709266-36b6db62bb6c4a81.png?imageMogr2/auto-orient/strip|imageView2/2/w/623/format/webp)
@@ -123,7 +127,8 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
共享内存使得多个进程可以可以直接读写同一块内存空间,是最快的可用 IPC 形式,是针对其他通信机制运行效率较低而设计的。共享内存往往与其他通信机制,如信号量配合使用,来实现进程间的同步和互斥通信。 共享内存使得多个进程可以可以直接读写同一块内存空间,是最快的可用 IPC 形式,是针对其他通信机制运行效率较低而设计的。共享内存往往与其他通信机制,如信号量配合使用,来实现进程间的同步和互斥通信。
![img](https://upload-images.jianshu.io/upload_images/5709266-29aa3e3d61e30c2a.png?imageMogr2/auto-orient/strip|imageView2/2/w/780/format/webp) ![共享内存](https://upload-images.jianshu.io/upload_images/7842464-49dd28489df7c751.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
@@ -133,10 +138,9 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
它是一种通信机制,凭借这种机制,既可以在本机进程间通信,也可以跨网络通过,因为,套接字通过网络接口将数据发送到本机的不同进程或远程计算机的进程。 它是一种通信机制,凭借这种机制,既可以在本机进程间通信,也可以跨网络通过,因为,套接字通过网络接口将数据发送到本机的不同进程或远程计算机的进程。
![socket套接字](https://upload-images.jianshu.io/upload_images/7842464-5ce209027aad3ab5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![img](https://upload-images.jianshu.io/upload_images/5709266-ccc181523c40ec60.png?imageMogr2/auto-orient/strip|imageView2/2/w/390/format/webp)
@@ -146,9 +150,7 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
### 线程概念 ### 线程概念
线程是操作操作系统能够进行运算调度的最小单位。线程被包含在进程之中,是进程中的实际运作单位,一个进程内可以包含多个线程,**线程是资源调度的最小单位。** 线程是操作操作系统能够进行运算调度的最小单位。线程被包含在进程之中,是进程中的实际运作单位,一个进程内可以包含多个线程,**线程是资源调度的最小单位。**
![进程线程关系](https://upload-images.jianshu.io/upload_images/7842464-ceb03bb0f45c2529.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![多线程程序模型](https://imgkr.cn-bj.ufileos.com/73d34b23-bb9d-4193-a496-b00eb036e05e.png)
### 多线程模型 ### 多线程模型
@@ -157,7 +159,7 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
于是,多线程服务模型出场。通过前面的学习我们知道,一个进程内的多个线程可以共享进程的全部系统资源。进程内创建的多个线程都可以访问进程内的全局变量。 于是,多线程服务模型出场。通过前面的学习我们知道,一个进程内的多个线程可以共享进程的全部系统资源。进程内创建的多个线程都可以访问进程内的全局变量。
当然没有免费的午餐,线程虽然能方便的访问进程资源,但也带来了额外的问题比如多线程访公共资源带来的同步与互斥问题,不同线程访问资源的先后顺序会相互影响,如果不做好同步和互斥会产生预期之外的结果,甚至死锁。 当然没有免费的午餐,线程虽然能方便的访问进程资源,但也带来了额外的问题。**比如多线程访公共资源带来的同步与互斥问题,不同线程访问资源的先后顺序会相互影响,如果不做好同步和互斥会产生预期之外的结果,甚至死锁。**
@@ -166,6 +168,10 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
多线程同步是线程之间的一种直接制约关系,一个线程的执行依赖另一个线程的通知,当它没有得到另一个线程的通知时必须等待,直到消息到达时才被唤醒,即有很强的执行先后关系。 多线程同步是线程之间的一种直接制约关系,一个线程的执行依赖另一个线程的通知,当它没有得到另一个线程的通知时必须等待,直到消息到达时才被唤醒,即有很强的执行先后关系。
比如你搭建了一个商城服务。这个服务的下单流程是这样的:第一步必须要先挑选商品加入购物车,第二步才能结账计算订单金额,假设这两个步骤的操作分别由两个线程去完成,则这两个线程的操作顺序很重要,必须是先下单再结账,这就是线程同步。 比如你搭建了一个商城服务。这个服务的下单流程是这样的:第一步必须要先挑选商品加入购物车,第二步才能结账计算订单金额,假设这两个步骤的操作分别由两个线程去完成,则这两个线程的操作顺序很重要,必须是先下单再结账,这就是线程同步。
![购物车](https://upload-images.jianshu.io/upload_images/7842464-7d5be1a8cff4d3e4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
@@ -175,6 +181,8 @@ CPU 密集型任务虽然也可以用多任务完成,但是任务越多,任
打个比方,你们班只有一台投影仪,当一个同学在上面放电影的时候,如果老师进来上课要用这个投影仪,那就只能由这个同学放弃投影仪的使用权,交给老师上课投影使用,对,教室里唯一的投影仪是共享资源,具有排他性,老师和学生比作是两个线程的话,那这两个线程是互斥的访问共享资源(投影仪)。 打个比方,你们班只有一台投影仪,当一个同学在上面放电影的时候,如果老师进来上课要用这个投影仪,那就只能由这个同学放弃投影仪的使用权,交给老师上课投影使用,对,教室里唯一的投影仪是共享资源,具有排他性,老师和学生比作是两个线程的话,那这两个线程是互斥的访问共享资源(投影仪)。
![投影仪](https://upload-images.jianshu.io/upload_images/7842464-b00adb79e813cb9b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### 多线程同步和互斥方法 ### 多线程同步和互斥方法
@@ -187,24 +195,7 @@ Linux 系统提供以下几种方法来解决多线程的同步和互斥问题
互斥锁接口函数: 互斥锁接口函数:
```c ![互斥锁api](https://upload-images.jianshu.io/upload_images/7842464-ffa131b62388e292.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#include <pthread.h>
//锁初始化
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
//互斥锁的销毁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//获得锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
//释放锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
```
#### 条件变量(同步) #### 条件变量(同步)
@@ -215,20 +206,7 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex);
条件变量系统 API 如下: 条件变量系统 API 如下:
```c ![条件变量API](https://upload-images.jianshu.io/upload_images/7842464-45eba3ee7a65bc69.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
// 初始化
int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
// 等待条件出现
int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);
int pthread_cond_destroy(pthread_cond_t *cond);
// 通知条件改变
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
```
#### 读写锁(同步) #### 读写锁(同步)
@@ -245,19 +223,7 @@ int pthread_cond_broadcast(pthread_cond_t *cond);
读写锁系统 API 读写锁系统 API
```c ![读写锁API](https://upload-images.jianshu.io/upload_images/7842464-a79fea4427e60dc5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#include<pthread.h>
// 初始化
int pthread_ rwlock_init( pthread_ rwlock_t *restrict rwlock,
const pthread _ rwlockattr_t *restrict attr);
// 加锁
int pthread_rwlock_rdlock ( pthread_ rwlock_t * rwlock);
int pthread_rwlock_wrlock ( pthread_ rwlock_t * rwlock);
// 解锁
int pthread_ rwlock_unlock( pthread_ rwlock_t * rwlock);
```
#### 自旋锁(同步) #### 自旋锁(同步)
@@ -268,23 +234,9 @@ int pthread_ rwlock_unlock( pthread_ rwlock_t * rwlock);
自旋锁在用户态使用的比较少,在内核使用的比较多。自旋锁适用于临界区代码比较短,锁的持有时间比较短的场景,否则会让其他线程一直等待造成饥饿现象。 自旋锁在用户态使用的比较少,在内核使用的比较多。自旋锁适用于临界区代码比较短,锁的持有时间比较短的场景,否则会让其他线程一直等待造成饥饿现象。
**自旋锁 API 接口** 自旋锁 API 接口
```c
#include <pthread.h>
// 加锁
int pthread_spin_lock(pthread_spinlock_t *lock);
int pthread_spin_trylock(pthread_spinlock_t *lock);
// 解锁
int pthread_spin_unlock(pthread_spinlock_t *lock);
// 创建和销毁
int pthread_spin_destroy(pthread_spinlock_t *lock);
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
```
![自旋锁API](https://upload-images.jianshu.io/upload_images/7842464-d3d5bf6bb398aec8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#### 信号量(同步与互斥) #### 信号量(同步与互斥)
@@ -299,28 +251,9 @@ int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
- 计数信号量。它可以有更大的取值范围,适用于临界代码允许有限数目的线程执行,就需要用到计数信号量。 - 计数信号量。它可以有更大的取值范围,适用于临界代码允许有限数目的线程执行,就需要用到计数信号量。
**信号量 API** 信号量 API
```c
#include<semaphore.h>
// 初始化
int sem_init (sem_t *sem , int pshared, unsigned int value);
// 等待信号量
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
// 释放信号量
int sem_post(sem_t *sem);
// 获取信号量
int sem_getvalue(sem_t* sem, int* sval)
// 销毁信号量
int sem_destroy(sem_t *sem);
```
![信号量API](https://upload-images.jianshu.io/upload_images/7842464-6b4c16c2b27701f4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 协程服务模型 ## 协程服务模型
@@ -329,11 +262,13 @@ int sem_destroy(sem_t *sem);
**那什么是协程呢?协程 `Coroutines` 是一种比线程更加轻量级的微线程。**类比一个进程可以拥有多个线程,一个线程也可以拥有多个协程,因此协程又称微线程和纤程。 **那什么是协程呢?协程 `Coroutines` 是一种比线程更加轻量级的微线程。**类比一个进程可以拥有多个线程,一个线程也可以拥有多个协程,因此协程又称微线程和纤程。
![协程图解](F:\github\lemonchann.github.io\_posts\linux\进程线程协程\协程图解.png) ![协程图解](https://upload-images.jianshu.io/upload_images/7842464-d7578a21d6777d42.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**可以粗略的把协程理解成子程序调用,每个子程序都可以在一个单独的协程内执行。** **可以粗略的把协程理解成子程序调用,每个子程序都可以在一个单独的协程内执行。**
![协程子程序模型](F:\github\lemonchann.github.io\_posts\linux\进程线程协程\协程子程序模型.png) ![协程子程序模型](https://upload-images.jianshu.io/upload_images/7842464-622364388e1ac260.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
@@ -343,17 +278,8 @@ int sem_destroy(sem_t *sem);
启动两个线程分别执行两个函数 `Do_some_IO``Do_some_process` ,第一个做耗时的 IO 处理操作,第二个对 IO 操作结果做快速的处理计算工作。伪代码如下: 启动两个线程分别执行两个函数 `Do_some_IO``Do_some_process` ,第一个做耗时的 IO 处理操作,第二个对 IO 操作结果做快速的处理计算工作。伪代码如下:
```c ![函数伪代码](https://upload-images.jianshu.io/upload_images/7842464-2618724977c152b6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
func Do_some_IO() {
printf("i am Do_some_IO");
// 做耗时的 IO 处理操作
}
func Do_some_process() {
printf("i am Do_some_process");
// 做快速的计算工作
}
```
多线程执行过程是这样的: 多线程执行过程是这样的:
@@ -364,7 +290,7 @@ func Do_some_process() {
3. 在消费者线程执行 `Do_some_process` 完成数据处理完成之前,生产者线程要阻塞等待。 3. 在消费者线程执行 `Do_some_process` 完成数据处理完成之前,生产者线程要阻塞等待。
4. 在消费者线程执行 `Do_some_process` 完成数据处理完成之后,要通知生成者线程继续 `Do_some_IO` 4. 在消费者线程执行 `Do_some_process` 完成数据处理完成之后,要通知生成者线程继续 `Do_some_IO`
![多线程执行模型](https://upload-images.jianshu.io/upload_images/7842464-c1236814c8f46ec6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**可以看到,多线程模型为了保证各个线程并行工作,需要额外做很多线程间的同步和通知工作,而且线程频繁的在阻塞和唤醒间切换,我们知道 Linux 下线程是轻量级线程 `LWP` ,每次线程切换涉及用户态和内核态的切换,还是很消耗性能的。** **可以看到,多线程模型为了保证各个线程并行工作,需要额外做很多线程间的同步和通知工作,而且线程频繁的在阻塞和唤醒间切换,我们知道 Linux 下线程是轻量级线程 `LWP` ,每次线程切换涉及用户态和内核态的切换,还是很消耗性能的。**
@@ -380,11 +306,12 @@ Do_some_process() // 计算处理协程
2. 在生产者协程工作期间,消费者协程保持等待。 2. 在生产者协程工作期间,消费者协程保持等待。
3. 当生产者协程完成 IO 处理,返回处理结果给消费者,并把程序执行权限交给消费者协程向下执行。 3. 当生产者协程完成 IO 处理,返回处理结果给消费者,并把程序执行权限交给消费者协程向下执行。
![协程执行时间线.png](https://upload-images.jianshu.io/upload_images/7842464-a904c0a135b21cfd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### 协程优势 ### 协程优势
- **由于协程在线程内实现,因此始终都是一个线程操作共享资源,所以不存在多线程抢占资源和资源同步问题。** - **由于协程在线程内实现,因此始终都是一个线程操作共享资源,所以不存在多线程抢占资源和资源同步问题。**
- **生产者协程和消费者协程,互相配合协作完成工作,而不是相互抢占,而且协程创建和切换的开销比线程小得多。** - **生产者协程和消费者协程,互相配合协作完成工作,而不是相互抢占,而且协程创建和切换的开销比线程小得多。**
@@ -395,16 +322,22 @@ Do_some_process() // 计算处理协程
**前面讲的多线程、多进程、协程都还只是软件层面的提高服务处理能力**。真正硬核的是从**硬件层面**提高处理能力,增加 CPU 物理核心数目,当然硬件都是有成本的,所以只有软件层面已经充分榨干性能才会考虑增加硬件。 **前面讲的多线程、多进程、协程都还只是软件层面的提高服务处理能力**。真正硬核的是从**硬件层面**提高处理能力,增加 CPU 物理核心数目,当然硬件都是有成本的,所以只有软件层面已经充分榨干性能才会考虑增加硬件。
不过,老板有钱买最好最贵的服务器另说,这是人民币玩家和穷逼玩家的区别了,软件工程师留下了贫困的泪水。 不过,老板有钱买最好最贵的服务器另说,这是人民币玩家和穷逼玩家的区别了,软件工程师留下了贫困的泪水。
![](https://upload-images.jianshu.io/upload_images/7842464-4842fc28adbc3f1e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### 增加机器核心数 ### 增加机器核心数
**CPU领域有一条摩尔定律大概 18 个月会将芯片的性能提高一倍**。现在这个定律变的越来越难以突破CPU 晶体管密度工作频率很难再提高,转而通过增加 CPU 核心数目的方式提高处理器性能。 **CPU领域有一条摩尔定律大概 18 个月会将芯片的性能提高一倍**。现在这个定律变的越来越难以突破CPU 晶体管密度工作频率很难再提高,转而通过增加 CPU 核心数目的方式提高处理器性能。
都2020年了商用服务器架构基本都是多核处理器多核的处理器的好处是能够真正做到程序并行运行处理效率大幅度提升那该如何查看 CPU 核心数目呢? ![cpu.jpg](https://upload-images.jianshu.io/upload_images/7842464-801dbf9d1282d265.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
目前商用服务器架构基本都是多核处理器,多核的处理器能够真正做到程序并行运行,处理效率大幅度提升,那该如何查看 CPU 核心数目呢?
对于 Windows 操作系统,打开任务管理器,通过界面的「内核」和「逻辑处理器」能看到。 对于 Windows 操作系统,打开任务管理器,通过界面的「内核」和「逻辑处理器」能看到。
![image-20200622140647284](C:\Users\linlongchen\AppData\Roaming\Typora\typora-user-images\image-20200622140647284.png) ![win 查看核心](https://upload-images.jianshu.io/upload_images/7842464-4386765b9cd315e7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
@@ -421,48 +354,15 @@ Do_some_process() // 计算处理协程
`cpuinfo` 输出示例: `cpuinfo` 输出示例:
```c ![cpuinfo](https://upload-images.jianshu.io/upload_images/7842464-ada58d977683c24c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 61
model name : Intel(R) Xeon(R) CPU E5-2667 v4 @ 3.20GHz
stepping : 2
microcode : 0x1
cpu MHz : 3192.606
cache size : 25600 KB
physical id : 0
siblings : 8
core id : 0
cpu cores : 8
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap xsaveopt arat
bogomips : 6385.21
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
power management:
```
#### 2. 通过编程接口查看 #### 2. 通过编程接口查看
除了上面以文件的形式查看 cpu 核心信息之外,系统还提供了编程接口可以查询,系统 API 如下。 除了上面以文件的形式查看 cpu 核心信息之外,系统还提供了编程接口可以查询,系统 API 如下。
```c ![查看核数API](https://upload-images.jianshu.io/upload_images/7842464-13e58fed363609b9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#include <unistd.h>
int sysconf(_SC_NPROCESSORS_ONLN);
#include <sys/sysinfo.h>
int get_nprocs_conf (void);
int get_nprocs (void);
```
@@ -477,18 +377,7 @@ CPU 亲和性是绑定某一进程或线程到特定的 CPU 或 CPU 集合,从
### 绑定进程 ### 绑定进程
在多进程模型中,绑定进程到特定的核心,下面是绑定进程的系统 API 在多进程模型中,绑定进程到特定的核心,下面是绑定进程的系统 API
![设置进程亲和性](https://upload-images.jianshu.io/upload_images/7842464-a5ff062125871f1f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
```c
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>
// 设置进程CPU亲和性
int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
// 获取进程CPU亲和性
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
```
@@ -496,20 +385,26 @@ int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
在多线程模型中,绑定线程到特定的核心,下面是绑定线程的系统 API 在多线程模型中,绑定线程到特定的核心,下面是绑定线程的系统 API
```c ![设置线程亲和性](https://upload-images.jianshu.io/upload_images/7842464-c32659e5e7552d3b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <pthread.h>
int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);
//Compile and link with -pthread.
```
## 总总结结
本文从程序任务类型出发,区分任务为 CPU 密集型和 IO 密集型两大类。接着分别说明提高基于这两类任务的服务性能方法,分为软件层面的方法和硬件层面的方法,其中软件层面主要讲述利用多进程、多线程以及协程模型,当然现有的技术还有 IO 多路复用、异步 IO 、池化技术等方案。讲到多线程和多进程,顺势说明了进程间通信和线程间同步互斥技术。
第二部分,讲解了从硬件层面提高服务性能:提高机器核心数,并教你如何查看 CPU 核心数的方法。最后,还可以通过软硬结合的方式,把硬件核心绑定到指定进程或者线程执行,最大程度的利用 CPU 性能。
希望通过本文的学习,读者对高性能服务模型有个初步的了解,并能对服务优化的方法和利弊举例一二,就是本文的价值所在。
## 再聊两句(求个三连)
感谢各位的阅读,文章的目的是分享对知识的理解,技术类文章我都会反复求证以求最大程度保证准确性,若文中出现明显纰漏也欢迎指出,我们一起在探讨中学习。
**如果觉得文章写的还行,对你有所帮助,不要白票 lemon动动手指点个「在看」或「分享」是对我持续创作的最大支持。**
今天的技术分享就到这里,我们下期再见。
## Reference ## Reference
@@ -518,7 +413,7 @@ int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuse
https://blog.csdn.net/gatieme/article/details/51481863 https://blog.csdn.net/gatieme/article/details/51481863
https://juejin.im/post/5b0014b7518825426e023666 https://juejin.im/post/5b0014b7518825426e023666
https://juejin.im/post/5c13245ee51d455fa5451f33 https://juejin.im/post/5c13245ee51d455fa5451f33
@@ -526,4 +421,6 @@ https://juejin.im/post/5b0014b7518825426e023666
https://www.jianshu.com/p/5788fb2345ce https://www.jianshu.com/p/5788fb2345ce
https://zhuanlan.zhihu.com/p/57470627 https://zhuanlan.zhihu.com/p/57470627
schnappi