并行
是指两个或者多个事件在同一时刻发生。并行是在不同实体上的多个事件。
并行针对多核 CPU 而言,它指的是多个核心同时执行多个任务的能力
单核 CPU 无法并行,并行只可能发生在多核 CPU 中。
并发
是指两个或多个事件在同一时间间隔发生。并发是在同一实体上的多个事件。
并发针对单核 CPU 而言,它指的是 CPU 交替执行不同任务的能力。
单核 CPU 只能并发,无法并行;换句话说,并行只可能发生在多核 CPU 中。
在多核 CPU 中,并发和并行一般都会同时存在,它们都是提高 CPU 处理任务能力的重要手段。
常见的3种并发办法:
1.基于进程的并发
2.IO多路复用
3.基于线程的并发
同步(Synchronization)
同步与异步关注的是消息通信机制,所谓同步,就是由“调用者”主动等待这个“调用”的结果。
阻塞、非阻塞、多路IO复用,都是同步IO,异步必定是非阻塞的,所以不存在异步阻塞和异步非阻塞的说法。真正的异步IO需要CPU的深度参与。换句话说,只有用户线程在操作IO的时候根本不去考虑IO的执行全部都交给CPU去完成,而自己只等待一个完成信号的时候,才是真正的异步IO。所以,拉一个子线程去轮询、去死循环,或者使用select、poll、epool,都不是异步。
和异步(Asynchronous)
异步则相反:“调用”在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立即得到结果。而是在“发出后”,“被调用者“通过状态,来通知调用者,或通过回调函数处理这个调用。 比如io完成端口,只有io完成端口才是真正的异步操作。
异步必定是非阻塞的。
阻塞
当数据没有准备的时候阻塞,往往需要等待缓冲区中的数据准备好过后才处理其他的事情,否則一直等待在那里。阻塞函数会挂起线程,释放cpu.
非阻塞
当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回,不会等待。如果数据已经准备好,也直接返回。
延伸:
就有3种思路:
1.多线程(同步阻塞);
2.IO多路复用(select,poll,epoll)(同步非阻塞,严格地来讲,是把阻塞点改变了位置);
3.直接暴露出异步的IO接口,如Linux kernel-aio(io_uring)和windows IOCP(异步非阻塞)。
其中:
select()函数主要解决的是accept()函数阻塞问题,而没有解决recv()和send()函数阻塞问题。
select不足的地方:
1 每次select都要把全部IO句柄复制到内核
2 内核每次都要遍历全部IO句柄,以判断是否数据准备好
3 select模式最大IO句柄数是1024,太多了性能下降明显