单线程

C++中多线程与Singleton的那些事儿

独自空忆成欢 提交于 2019-12-21 23:50:39
前言 前段时间在网上看到了个的面试题,大概意思是如何在不使用锁和C++11的情况下,用C++实现线程安全的Singleton。 看到这个题目后,第一个想法就是用Scott Meyer在《Effective C++》中提到的,在static成员函数中构造local static变量的方法来实现,但是经过一番查找、思考,才明白这种实现在某些情况下是有问题的。本文主要将从最基本的单线程中的Singleton开始,慢慢讲述多线程与Singleton的那些事。 单线程 在单线程下,下面这个是常见的写法: template<typename T> class Singleton { public: static T& getInstance() { if (!value_) { value_ = new T(); } return *value_; } private: Singleton(); ~Singleton(); static T* value_; }; template<typename T> T* Singleton<T>::value_ = NULL; 在单线程中,这样的写法是可以正确使用的,但是在多线程中就不行了。 多线程加锁 在多线程的环境中,上面单线程的写法就会产生race condition从而产生多次初始化的情况。要想在多线程下工作

JavaScript执行机制

喜夏-厌秋 提交于 2019-12-20 02:42:39
原文   简书原文:https://www.jianshu.com/p/0d2d42fbe1dc 大纲   1、场景分析   2、执行机制相关知识点   3、以实例来说明JavaScript的执行机制   4、相关概念 1、场景分析 /* 以下这段代码的执行结果是什么? 如果依照:js是按照语句出现的顺序执行这个理念, 那么代码执行的结果应该是: //"定时器开始啦" //"马上执行for循环啦" //"执行then函数啦" //"代码执行结束" 但结果并不是这样的,得到的结果是: //"马上执行for循环啦" //"代码执行结束" //"执行then函数啦" //"定时器开始啦" */ setTimeout(function(){ console.log('定时器开始啦') }); new Promise(function(resolve){ console.log('马上执行for循环啦'); for(var i = 0; i < 10000; i++){ i == 99 && resolve(); } }).then(function(){ console.log('执行then函数啦') }); console.log('代码执行结束'); 2、执行机制相关知识点 2.1、关于javascript   javascript是一门单线程语言,在最新的HTML5中提出了Web

python协程的理解

十年热恋 提交于 2019-12-19 09:48:57
一、介绍 什么是并发? 并发的本质就是切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制): 1.任务发生阻塞 2.计算任务时间过长,需要让出cpu给高优先级的程序 协程,又称微线程,是一种用户态的轻量级线程。协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置,当程序中存在大量不需要CPU的操作时(IO),适用于协程。 协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换 进程有三种状态,而线程是进程的执行最小单位,所以也是线程的三种状态 二、协程切换 1.yield是一种在单线程下可以保存任务运行状态的方法 1. yiled 可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 2. send 可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 通过yield实现任务切换+保存线程: import time def func1(): for i in range(11): print('func1第%s次打印' % i) time

服务器模型——从单线程阻塞到多线程非阻塞(上)

你离开我真会死。 提交于 2019-12-17 01:08:42
https://blog.csdn.net/s3FRH3JyN6yymHmT11/article/details/78871563 前言的前言 服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: 单线程/多线程阻塞I/O模型 单线程非阻塞I/O模型 多线程非阻塞I/O模型,Reactor及其改进 前言 这里探讨的服务器模型主要指的是服务器端对I/O的处理模型。从不同维度可以有不同的分类,这里从I/O的阻塞与非阻塞、I/O处理的单线程与多线程角度探讨服务器模型。 对于I/O,可以分成阻塞I/O与非阻塞I/O两大类型。阻塞I/O在做I/O读写操作时会使当前线程进入阻塞状态,而非阻塞I/O则不进入阻塞状态。 对于线程,单线程情况下由一条线程负责所有客户端连接的I/O操作,而多线程情况下则由若干线程共同处理所有客户端连接的I/O操作。 单线程阻塞I/O模型 单线程阻塞I/O模型是最简单的一种服务器模型,几乎所有程序员在刚开始接触网络编程时都从这个简单的模型开始。这种模型只能同时处理一个客户端访问,并且在I/O操作上是阻塞的,线程会一直在等待,而不会做其他事情。对于多个客户端访问,必须要等到前一个客户端访问结束才能进行下一个访问的处理,请求一个一个排队,只提供一问一答服务。 首先,服务器必须初始化一个套接字服务器,并绑定某个端口号并使之监听客户端的访问

服务器模型——从单线程阻塞到多线程非阻塞(下)

邮差的信 提交于 2019-12-17 00:23:16
https://blog.csdn.net/s3FRH3JyN6yymHmT11/article/details/78976284 前言的前言 服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: * 单线程/多线程阻塞I/O模型 * 单线程非阻塞I/O模型 * 多线程非阻塞I/O模型,Reactor及其改进 前言 这里探讨的服务器模型主要指的是服务器端对I/O的处理模型。从不同维度可以有不同的分类,这里从I/O的阻塞与非阻塞、I/O处理的单线程与多线程角度探讨服务器模型。 对于I/O,可以分成阻塞I/O与非阻塞I/O两大类型。阻塞I/O在做I/O读写操作时会使当前线程进入阻塞状态,而非阻塞I/O则不进入阻塞状态。 对于线程,单线程情况下由一条线程负责所有客户端连接的I/O操作,而多线程情况下则由若干线程共同处理所有客户端连接的I/O操作。 多线程非阻塞I/O模型 单线程非阻塞I/O模型已经大大提高了机器的效率,而在多核的机器上可以通过多线程继续提高机器效率。最朴实、最自然的做法就是将客户端连接按组分配给若干线程,每个线程负责处理对应组内的连接。如图所示,有4个客户端访问服务器,服务器将套接字1和套接字2交由线程1管理,而线程2则管理套接字3和套接字4,通过事件检测及非阻塞读写就可以让每个线程都能高效处理。 最经典的多线程非阻塞I

服务器模型——从单线程阻塞到多线程非阻塞(中)

旧时模样 提交于 2019-12-16 23:54:48
https://blog.csdn.net/wangyangzhizhou/article/details/78899629 前言的前言 服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: * 单线程/多线程阻塞I/O模型 * 单线程非阻塞I/O模型 * 多线程非阻塞I/O模型,Reactor及其改进 前言 这里探讨的服务器模型主要指的是服务器端对I/O的处理模型。从不同维度可以有不同的分类,这里从I/O的阻塞与非阻塞、I/O处理的单线程与多线程角度探讨服务器模型。 对于I/O,可以分成阻塞I/O与非阻塞I/O两大类型。阻塞I/O在做I/O读写操作时会使当前线程进入阻塞状态,而非阻塞I/O则不进入阻塞状态。 对于线程,单线程情况下由一条线程负责所有客户端连接的I/O操作,而多线程情况下则由若干线程共同处理所有客户端连接的I/O操作。 单线程非阻塞I/O模型 多线程阻塞I/O模型通过引入多线程确实提高了服务器端的并发处理能力,但每个连接都需要一个线程负责I/O操作。当连接数量较多时可能导致机器线程数量太多,而这些线程大多数时间却处于等待状态,造成极大的资源浪费。鉴于多线程阻塞I/O模型的缺点,有没有可能用一个线程就可以维护多个客户端连接并且不会阻塞在读写操作呢?下面介绍单线程非阻塞I/O模型。 单线程非阻塞I/O模型最重要的一个特点是

单线程排序和利用Fork/Join进行多线程并行排序的简单对比

主宰稳场 提交于 2019-12-15 11:53:13
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Fork/Join框架自从在JDK7中引进之后,对并行计算的设计带来了更多便利。 本文使用java原生的排序方法Array.sort单线程排序,和利用Fork/Join框架进行任务分割设计的快速排序进行对比。 首先,使用以下方法构造一个简单的文件样本,目标是生成一个文本文件,10000000行,每行为一个20000以内的随机数: package sort; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Random; public class GenerateSample { public static void main(String[] args) { File f = new File("/home/nox/java/sort/sample.txt"); FileWriter writer; try { writer = new FileWriter(f, false); Random random1 = new Random(10); for (int i = 0; i < 10000000; i++) { writer.write(String.valueOf

spring boot 默认单线程排队跑定时任务问题记录

人盡茶涼 提交于 2019-12-14 22:40:15
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> ** 问题描述:在使用springboot默认的定时任务时,若存在多个任务,框架默认只启动一个线程执行,会导致有些任务不能在指定时间开始执行** ** 另,关于分布式下定时任务同步锁问题,会再单独写一篇记录** 测试默认情况下定时任务的线程名称: package com.example.demo.job; import net.javacrumbs.shedlock.core.SchedulerLock; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; @Component @EnableScheduling public class TestJob { @Scheduled(cron = "0/5 * * * * ?") @SchedulerLock(name = "test1-task", lockAtMostForString = "PT28M

协程

孤人 提交于 2019-12-09 19:27:41
目录 一 什么是协程? 二 协程介绍 三 Gevent 一 什么是协程? ​ 进程:资源单位 ​ 线程:执行单位 ​ 协程:单线程下实现并 在IO密集型的情况下,使用协程能提高最高效率 注意:协程不是任何单位,只是程序员YY出来的东西 手动实现 “遇到IO切换 + 保存状态“ 去欺骗操作系统,让操作系统误以为没有IO操作,将CPU的执行权限给你 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制), 第一种情况是该任务发生了阻塞 第二种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它 一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。 为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: #1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 单纯的切换反而会降低运行效率 ''' 1、协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点:

理解Redis的单线程模式

亡梦爱人 提交于 2019-12-09 13:19:55
0.概述 本文基于的Redis版本为4.0以下,在Redis更高版本中并不是完全的单线程了, 增加了BIO线程 ,本文主要讲述主工作线程的单线程模式。 通过本文将了解到以下内容: Redis服务器采用单线程模型的原因 Redis单线程处理文件事件和时间事件 Redis事件的执行和调度 1.Redis的单线程模式 单线程的现状 本质上Redis并不是单纯的单线程服务模型,一些辅助工作比如持久化刷盘、惰性删除等任务是由BIO线程来完成的,这里说的单线程主要是说与客户端交互完成命令请求和回复的工作线程。 单线程的原因 至于Antirez大佬当时是怎么想的设计为单线程不得而知,只能从几个角度来分析,来确定单线程模型的选择原因: CPU并非瓶颈 多线程模型主要是为了充分利用多核CPU,让线程在IO阻塞时被挂起让出CPU使用权交给其他线程,充分提高CPU的使用率,但是这个场景在Redis并不明显,因为CPU并不是Redis的瓶颈,Redis的所有操作都是基于内存的,处理事件极快,因此使用多线程来切换线程提高CPU利用率的需求并不强烈; 内存才是瓶颈 单个Redis实例对单核的利用已经很好了,但是Redis的瓶颈在于内存,设想64核的机器假如内存只有16GB,那么多线程Redis有什么用武之地? 复杂的Value类型 Redis有丰富的数据结构,并不是简单的Key-Value型的NoSQL