单线程

对Redis 单进程、单线程模型的理解(网摘)

巧了我就是萌 提交于 2019-12-09 11:42:34
1、基本原理 采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗) (1)为什么不采用多进程或多线程处理? 多线程处理可能涉及到锁 多线程处理会涉及到线程切换而消耗CPU (2)单线程处理的缺点? 无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善 2、Redis不存在线程安全问题? Redis采用了线程封闭的方式,把任务封闭在一个线程,自然避免了线程安全问题,不过对于需要依赖多个redis操作的复合操作来说,依然需要锁,而且有可能是分布式锁 3、什么是多路I/O复用(Epoll) (1) 网络IO都是通过Socket实现,Server在某一个端口持续监听,客户端通过Socket(IP+Port)与服务器建立连接(ServerSocket.accept),成功建立连接之后,就可以使用Socket中封装的InputStream和OutputStream进行IO交互了。针对每个客户端,Server都会创建一个新线程专门用于处理 (2) 默认情况下,网络IO是阻塞模式,即服务器线程在数据到来之前处于【阻塞】状态,等到数据到达,会自动唤醒服务器线程,着手进行处理。阻塞模式下,一个线程只能处理一个流的IO事件 (3) 为了提升服务器线程处理效率,有以下三种思路 (1)非阻塞【忙轮询】:采用死循环方式轮询每一个流,如果有IO事件就处理

Netty Reactor 线程模型笔记

白昼怎懂夜的黑 提交于 2019-12-09 11:07:14
引用: https://www.cnblogs.com/TomSnail/p/6158249.html https://www.cnblogs.com/heavenhome/articles/6554262.html https://my.oschina.net/andylucc/blog/614295 1.3 Reactor Reactor是一个同步的I/O多路复用模型,它没有Proactor模式那么复杂,原理图如下: 用户发起IO操作到事件分离器 事件分离器调用相应的处理器处理事件 事件处理完成,事件分离器获得控制权,继续相应处理 1.4 Proactor和Reactor的比较 Reactor模型简单,Proactor复杂 Reactor是同步处理方式,Proactor是异步处理方式 Proactor的IO事件依赖操作系统,操作系统须支持异步IO 同步与异步是相对于服务端与IO事件来说的,Proactor通过操作系统异步来完成IO操作,当IO完成后通知事件分离器,而Reactor需要自己完成IO操作 2 Reactor多线程模型 前面已经简单介绍了Proactor和Reactor模型,在实际中Proactor由于需要操作系统的支持,实现的案例不多,有兴趣的可以看一下Boost Asio的实现,我们主要说一下Reactor模型,Netty也是使用Reactor实现的。

python:协程的介绍

匆匆过客 提交于 2019-12-06 11:04:51
    cpu 正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制):   ​一种情况是该任务发生了阻塞;   另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它。 1、什么是协程?    协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到 I/O 自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换。 2、通过yield实现协程   上述第二种情况并不能提升效率,只是为了让 cpu 能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。为此我们可以基于 yield 来验证。 yield 本身就是一种在单线程下可以保存任务运行状态的方法   第一种情况的切换。在任务一遇到 io 情况下,切到任务二去执行,这样就可以利用任务一阻塞的时间完成任务二的计算,效率的提升就在于此。    yiled 可以保存状态, yield 的状态保存与操作系统的保存线程状态很像,但是 yield 是代码级别控制的,更轻量级    send 可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 import time def consumer(): while True: x=yield

为什么说Redis是单线程的以及Redis为什么这么快!(转)

笑着哭i 提交于 2019-12-05 19:12:58
一、前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”、什么是“热数据和冷数据”,复杂一点的会问到缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题,这些看似不常见的概念,都与我们的缓存服务器相关,一般常用的缓存服务器有Redis、Memcached等,而笔者目前最常用的也只有Redis这一种。 如果你在以前面试的时候还没有遇到过面试官问你《为什么说Redis是单线程的以及Redis为什么这么快!》,那么你看到这篇文章的时候,你应该觉得是一件很幸运的事情!如果你刚好是一位高逼格的面试官,你也可以拿这道题去面试对面“望穿秋水”般的小伙伴,测试一下他的掌握程度。 好啦!步入正题!我们先探讨一下Redis是什么,Redis为什么这么快、然后在探讨一下为什么Redis是单线程的? 二、Redis简介 Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件。 它支持多种类型的数据结构,如字符串(Strings),散列(Hash),列表(List),集合(Set),有序集合(Sorted Set或者是ZSet)与范围查询,Bitmaps,Hyperloglogs 和地理空间(Geospatial)索引半径查询。其中常见的数据结构类型有:String、List、Set、Hash、ZSet这5种。 Redis 内置了复制

一个前端工程师眼里的NodeJS

你离开我真会死。 提交于 2019-12-05 15:25:56
JavaScript单线程的误解   在我接触JavaScript(无论浏览器还是NodeJS)的时间里,总是遇到有朋友有多线程的需求。而在NodeJS方面,有朋友甚至直接说到,NodeJS是单线程的,无法很好的利用多核CPU。   诚然,在前端的浏览器中,由于前端的JavaScript与UI占据同一线程,执行JavaScript确实为UI响应造成了一定程度上的麻烦。但是,除非用到超大的循环语句执行JavaScript,或是用阻塞式的Ajax,或是太过频繁的定时器执行外,JavaScript并没有给前端应用带来明显的问题,所以也很少有朋友抱怨JavaScript是单线程而不能很好利用多核CPU的问题,因为没有因此出现性能瓶颈。   但是,我们可以用Ajax和Web Worker回应这个误解。当Ajax请求发送之后,除非是同步请求,否则其余的JavaScript代码会很快被执行到。在Ajax发送完成,直到接收到响应的这段时间里,这个网络请求并不会阻塞JavaScript的执行,而网络请求已经发生,这是必然的事。那么,答案就很明显了,JavaScript确实是执行在单线程上的,但是,整个Web应用执行的宿主(浏览器)并非以单线程的方式在执行。而Web Worker的诞生,就是直接为了解决JavaScript与UI占用同一线程造成的UI响应问题的

《深入浅出NodeJS》读书笔记

爷,独闯天下 提交于 2019-12-05 14:33:48
 NodeJS NodeJS 4 个特点: 异步 I/O, 事件驱动与回调, 单线程事件轮询, 跨平台。 NodeJS 5 个大坑:异常处理,嵌套太深,没有 Sleep ,多线程编程,异步转同步。 NodeJS 4 种提升性能的方法: 动静分离, 缓存( Redis ) , 多进程, 数据库读写分离。 NodeJS 简介 模块机制 异步 I/O 异步编程 内存控制 Buffer 网络编程 构建 Web 多进程 测试 产品化 调试 NodeJS 编程规范 NodeJS 简介 高性能,符合时间驱动,没有历史包袱这三个主要原因, JavaScript 成为了 Node 的实现语言。 NodeJS 基于 Google V8 引擎。 Node 优秀的运算能力主要来自 V8 的深度优化。 NodeJS 特点:异步 I/O, 事件驱动与回调函数, 单线程事件轮询,跨平台 NodeJS 单线程的缺点: 无法利用多核 CPU. 错误会引起整个应用进程退出。 大量计算占用 CPU 导致无法继续调用异步 I/O. 解决单线程缺点的方法是引入子进程方法( Cluster, 见后边)和 C/C++ 模块扩展(利用它们的多线程机制)。 模块机制 Node 出现之前,服务器端的 JS 基本没有市场的。 CommonJS 主要是为了弥补当前 JS 没有标准的缺陷,希望 JS 能够在任何地方运行。 模块引用

redis的单线程

£可爱£侵袭症+ 提交于 2019-12-05 09:05:53
一、redis为什么这么快 1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1); 2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的; 3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗; 4、使用多路I/O复用模型,非阻塞IO; 这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量。 5. 还有一点,Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。 二、为什么Redis是单线程的 官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)。 但是

redis高并发总结

社会主义新天地 提交于 2019-12-05 06:50:48
Redis是单线程的,省去了很多上下文切换线程的时间;(官方答案:因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。) Redis在内存中存储,读写速度非常快。 单线程不用考虑锁的消耗问题。 Redis 采用网络IO多路复用技术来保证在多连接系统的高吞吐量。多路复用在以后的博客中会写 Redis 采用hash数据结构,速度快 来源: https://www.cnblogs.com/vinic-xxm/p/11911650.html

Python多线程/单线程

六月ゝ 毕业季﹏ 提交于 2019-12-05 03:14:28
定义1、进程:就是一组资源的集合。一个程序就是一个进程。 线程是用来干活的,只有进程的话是没办法运行的,进程里其实是线程在具体干活的。 线程和线程之间是互相独立的。 import threading #引入线程模块 import time def run(): time.sleep(5) print('over') start_time=time.time() run() run() run() run() end_time=time.time() print('run_time', end_time-start_time) #结果:run_time=20.38954234234 上面这个例子是单线程执行的,运行时间是20多秒,如果使用多线程,则会并行执行,执行结果应该是5秒左右。 import threading import time def run(): time.sleep(5) print('over') start_time=time.time() thread_list = [] for i in range(5): t=threading.Thread(target=run) #实例化一个线程 t.start() #启动这个线程 thread_list.append(t) for thread in thread_list: thread.join()

Golang panic 异常捕获

徘徊边缘 提交于 2019-12-05 00:16:37
1. panic异常是伴随协程的,所以在做并发时也一定要在每一个协程中对panic进行捕获和处理 2. 单线程程序修改为并发操作是要格外小心,原来单线程下在request入口处一个panic异常处理就可以保证主程序不会因panic和宕机,现在每一个并发程序中都需要加上该异常处理。 2019-06-17 来源: CSDN 作者: ye_guoyun 链接: https://blog.csdn.net/ye_guoyun/article/details/92712437