mirror of
https://github.com/Estom/notes.git
synced 2026-02-03 02:23:31 +08:00
并行编程
This commit is contained in:
0
C++/web开发/sougou-workflow.md
Normal file
0
C++/web开发/sougou-workflow.md
Normal file
@@ -182,7 +182,7 @@ delete [] pa;
|
||||
* unique_ptr动态数组版本
|
||||
|
||||
```
|
||||
unique_ptr<int[]> up(new int[[10]]);
|
||||
unique_ptr<int[]> up(new int[10]);
|
||||
up.release();
|
||||
```
|
||||

|
||||
|
||||
@@ -288,6 +288,8 @@ int main()
|
||||
### package_task说明
|
||||
* 是一个线程池,可以用来多次启动某一个线程。
|
||||
* 是async方法的扩展版,通过return语句来抛出一个默认的promise,解锁future的执行。
|
||||
|
||||
|
||||
|函数|作用|
|
||||
|---|---|
|
||||
get_future|返回与承诺的结果关联的 std::future
|
||||
|
||||
@@ -42,7 +42,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *
|
||||

|
||||
|
||||
### I/O 复用(事件驱动IO)
|
||||
|
||||
* I/O多路复用。I/O指的是I/O事件(包括I/O读写、I/O异常等事件),多路指多个独立连接(或多个Channel),复用指多个事件复用一个控制流(线程或进程)。串起来理解就是很多个独立I/O事件的处理依赖于一个控制流。
|
||||
* 主要是select、poll、epoll;对一个IO端口,两次调用,两次返回,比阻塞IO并没有什么优越性;关键是能实现同时对**多个IO端口进行监听**;
|
||||
* I/O复用模型会用到select、poll、epoll函数,这几个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。当某一个套接字可读时返回,之后再使用 recvfrom 把数据从内核复制到进程中。
|
||||
* 它可以让**单个进程具有处理多个 I/O 事件的能力**。又被称为 Event Driven I/O,即**事件驱动 I/O**。
|
||||
|
||||
@@ -14,6 +14,17 @@
|
||||
* **异步式 I/O (Asynchronous I/O)或非阻塞式I/O (Non-blocking I/O)**。则针对所有I/O 操作不采用阻塞的策略。当线程 遇到I/O 操作时,不会以阻塞的方式等待I/O 操作的完成或数据的返回,而只是将I/O 请求发送给操作系统,继续执行下一条语句。当操作系统完成I /O 操作时,以事件的形式通知执行I/O 操作的线程,线程会在特定时候处理这个事件。为了处理异步I/O,线程必须有事件循环,不断地检查有没有未处 理的事件,依次予以处理。
|
||||
* **并发方式**。阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须通过**多线程**。而非阻塞模式下,一个线程永远在执行计算操作,这个线程所使用的CPU 核心利用率永远是100%,**I/O 以事件的方式通知**。在阻塞模式下,多线程往往能提高系统吞吐量,因为一个线程阻塞时还有其他线程在工作,多线程可以让CPU 资源不被阻塞中的线程浪费。而在非阻塞模式下,线程不会被I/O 阻塞,永远在利用CPU。多线程带来的好处仅仅是在多核CPU 的情况下利用更多的核,而Node.js的单线程也能带来同样的好处。这就是为什么Node.js 使用了单线程、非阻塞的**事件编程模式**。
|
||||
|
||||
|
||||
### 一种更深的理解——在看完五种IO模型之后的反思
|
||||
|
||||
* 同步和异步是针对**应用程序和内核**的交互而言的;
|
||||
* 同步指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪。
|
||||
* 异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知。
|
||||
* 阻塞和非阻塞是针对于**进程在访问数据**的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作函数的实现方式;
|
||||
* 阻塞方式下读取或者写入函数将一直等待,
|
||||
* 非阻塞方式下,读取或者写入函数会立即返回一个状态值。
|
||||
|
||||
|
||||
### 同步异步
|
||||
|
||||
* 同步与异步关注的是消息通信机制。是**两个进程之间的关系**。
|
||||
@@ -27,13 +38,23 @@
|
||||
* 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
|
||||
* 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
|
||||
|
||||
## 3 实现方式
|
||||
|
||||
## 3 实现方式
|
||||
### 同步阻塞通信
|
||||
* java socket网络编程,都是阻塞通信。接收端在接受到数据之前,一直处于阻塞状态。通过多线程实现并行编程。
|
||||
> 在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。
|
||||
|
||||
* java 传统的IO和socket网络编程,都是阻塞通信。接收端在接受到数据之前,一直处于阻塞状态。通过多线程实现并行编程。
|
||||
* 在linux下,select/poll/epoll也是同步阻塞IO,也被称为事件IO,同时堵塞多个IO。不需要多线程,当某个IO可用时,发送IO事件,使用事件驱动的IO实现并行编程。
|
||||
* 普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事。也是通过开启多个浏览器线程实现并行编程。
|
||||
|
||||
### 同步非阻塞
|
||||
> 在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。
|
||||
|
||||
* poll机制。轮训IO信号,虽然没有阻塞,但是在循环中一致确认IO是否完成。效率很低。
|
||||
|
||||
|
||||
### 异步非阻塞通信
|
||||
> 在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。目前Java中还没有支持此种IO模型
|
||||
|
||||
* node.js是单线程的异步非阻塞(事件循环检测通知的机制);
|
||||
* windows完全端口是机器上有几个cpu创建几个线程的异步非阻塞机制(多线程池 + 事件触发机制)
|
||||
@@ -41,13 +62,15 @@
|
||||
* ajax请求(异步): 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕
|
||||
|
||||
|
||||
### 同步非阻塞
|
||||
### 异步阻塞通信
|
||||
|
||||
* poll机制。轮训IO信号,虽然没有阻塞,但是在循环中一致确认IO是否完成。效率很低。
|
||||
> 此种方式下是指应用发起一个IO操作以后,不等待内核IO操作的完成,等内核完成IO操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问IO是否完成,那么为什么说是阻塞的呢?因为此时是通过select系统调用来完成的,而select函数本身的实现方式是阻塞的,而采用select函数有个好处就是它可以同时监听多个文件句柄,从而提高系统的并发性!
|
||||
|
||||
|
||||
### 实现并行编程的几种方法
|
||||
|
||||
1. java 多线程
|
||||
2. nodejs 异步回调
|
||||
3. linux IO复用。epoll事件回调
|
||||
3. linux IO复用。epoll事件回调
|
||||
|
||||
> 这里所谓的什么机制、什么方法。都是设计模式的一部分。通过某种设计模式,实现并行编程:异步回调模式、事件回调模式等。
|
||||
Reference in New Issue
Block a user