python多线程并发

Python学习day38-并发编程(线程)

假如想象 提交于 2019-11-29 21:34:39
/*--> */ /*--> */ Python学习day38-并发编程(线程) 线程的概念 开启线程的两种方式 线程和进程 线程的一些其他用法 Python学习day38-并发编程(线程) 线程的概念 前面我们已经了解了进程的概念,我们知道,进程有很多的优点,他提供了多道编程以及并发的方式,可以让每个进程都有自己的CPU和各种资源,极大的提高了计算机的效率,那么为什么还要引入线程的概念呢,我们就用多进程来编程不好么? 答案就是,不好,因为进程也是有缺陷的,主要体现在两个方面:一个就是一个进程在同一时间只能干一件事情,同时开过多的子进程的话会过量的占用系统资源,另外一点就是,进程在执行过程中如果被阻塞的话,整个进程就会挂起,不会继续往下运行,也不会自己结束,一直占据着系统的一部分资源,造成浪费. 所以线程到底是什么呢?答案就出来了: 进程是 资源分配 最小的单位,而线程则是 CPU调度 的最小单位,每一个进程中至少有一个线程,注意,至少一个,多者不限. 开启线程的两种方式 线程主要用的模块是threading,导入的是Thread类,以此来实例化开启线程,实际开启线程的方式与开启进程十分相似,见下例: xxxxxxxxxx 18 1 # 方式一 2 # 通过定义函数的方式,在main函数里面直接调用Thread来开启线程 3 from threading import Thread

python之路——线程

狂风中的少年 提交于 2019-11-29 21:33:11
简介 操作系统线程理论 线程概念的引入背景 线程的特点 进程和线程的关系 使用线程的实际场景 用户级线程和内核级线程(了解) 线程和python 理论知识 线程的创建Threading.Thread类 锁 队列 Python标准模块--concurrent.futures 回到顶部 操作系统线程理论 回到顶部 线程概念的引入背景 进程   之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。 有了进程为什么要有线程   进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率。很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上: 进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。 进程在执行的过程中如果阻塞,例如等待输入

Python常见面试题四:爬虫和数据库部分

被刻印的时光 ゝ 提交于 2019-11-29 21:24:46
目录 1. scrapy 和 scrapy-redis 有什么区别?为什么选择 redis 数据库? 2. 用过的爬虫框架或者模块有哪些?谈谈他们的区别或者优缺点? 3. 常用的 mysql 引擎有哪些?各引擎间有什么区别? 4. 描述下 scrapy 框架运行的机制? 5. 什么是关联查询,有哪些? 6. 写爬虫是用多进程好?还是多线程好? 为什么? 7. 数据库的优化? 8. 常见的反爬虫和应对方法? 9. 分布式爬虫主要解决什么问题? 10. 爬虫过程中验证码怎么处理? 1. scrapy 和 scrapy-redis 有什么区别?为什么选择 redis 数据库? 1) scrapy 是一个 Python 爬虫框架,爬取效率极高,具有高度定制性,但是不支持分布式。而 scrapy-redis 一套基于 redis 数据库、运行在 scrapy 框架之上的组件,可以让 scrapy 支持分布式策略,Slaver 端共享 Master 端 redis 数据库里的 item 队列、请求队列和请求指纹集合。 2) 为什么选择 redis 数据库,因为 redis 支持主从同步,而且数据都是缓存在内存中的,所以基于 redis 的分布式爬虫,对请求和数据的高频读取效率非常高。 2. 用过的爬虫框架或者模块有哪些?谈谈他们的区别或者优缺点? Python自带:urllib,urllib2

面试365

故事扮演 提交于 2019-11-29 19:50:11
1、一行代码实现1--100之和 2、如何在一个函数内部修改全局变量 3、列出5个python标准库 os:提供了不少与操作系统相关联的函数 sys: 通常用于命令行参数 re: 正则匹配 math: 数学运算 datetime:处理日期时间 4、字典如何删除键和合并两个字典 执行结果 5、谈下python的GIL python的GIL是python的全局解释器锁,同一个进程中如果有多个线程运行,一个线程运行的时候会霸占解释器,上了个锁即GIL,进程内其他线程无法运行。如果遇到耗时操作,GIL会打开,其他线程先运行,所以多线程仍然是有先后顺序的。 6、python实现列表去重的方法 执行结果 7、fun(*args,**kwargs)中的*args,**kwargs什么意思? 用于函数的接收参数。可以接收补丁数量的参数。 *args是用来接收一个非键值对的可变数量的参数列表 **kwargs允许接收不定长度的键值对。 8、简述with方法打开处理文件帮我我们做了什么? 9、列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并使用列表推导式提取出大于10的数,最终输出[16,25] 执行结果 10、python中生成随机整数、随机小数、0--1之间小数方法 随机整数:random.randint(a,b),生成区间内的整数 随机小数:习惯用numpy库

python网络进程

谁说我不能喝 提交于 2019-11-29 19:07:06
多任务编程 意义 :充分利用计算机的资源提高程序的运行效率 定义 :通过应用程序利用计算机多个核心,达到同时执行多个任务的目的 实施方案 : 多进程 、 多线程 并行 :多个计算机核心 并行的 同时处理 多个任务 并发 :内核在 多个任务间 不断 切换 ,达到好像内核在同时处理多个任务的运行效果 进程 :程序在计算机中运行一次的过程 程序 :是一个可执行文件,是静态的,占有磁盘,不占有计算机运行资源 进程 :进程是一个动态的过程描述,占有CPU内存等计算机资源的,有一定的生命周期 * 同一个程序的不同执行过程是不同的进程,因为分配的计算机资源等均不同 父子进程 : 系统中每一个进程(除了系统初始化进程)都有唯一的父进程,可以有0个或多个子进 程。父子进程关系便于进程管理。 进程 CPU时间片: 如果一个进程在某个时间点被计算机分配了内核,我们称为该进程在CPU时间片上。 PCB( 进程控制块):存放进程消息的空间 进程ID(PID):进程在操作系统中的唯一编号,由系统自动分配 进程信息包括:进程PID,进程占有的内存位置,创建时间,创建用户. . . . . . . . 进程特征: 进程是操作系统分配计算机资源的最小单位 每一个进程都有自己单独的 虚拟 内存空间 进程间的执行相互独立,互不影响 进程的状态 1、 三态 就绪态: 进程具备执行条件, 等待系统分配CPU 运行态: 进程

python基于redis实现分布式锁

家住魔仙堡 提交于 2019-11-29 17:04:10
一、什么是分布式锁 我们在开发应用的时候,如果需要对某一个共享变量进行多线程同步访问的时候,可以使用我们学到的锁进行处理,并且可以完美的运行,毫无Bug! 注意这是单机应用,后来业务发展,需要做集群,一个应用需要部署到几台机器上然后做负载均衡,大致如下图: 上图可以看到,变量A存在三个服务器内存中(这个变量A主要体现是在一个类中的一个成员变量,是一个有状态的对象),如果不加任何控制的话,变量A同时都会在分配一块内存,三个请求发过来同时对这个变量操作,显然结果是不对的!即使不是同时发过来,三个请求分别操作三个不同内存区域的数据,变量A之间不存在共享,也不具有可见性,处理的结果也是不对的! 如果我们业务中确实存在这个场景的话,我们就需要一种方法解决这个问题! 为了保证一个方法或属性在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署的情况下,可以使用并发处理相关的功能进行互斥控制。但是,随着业务发展的需要,原单体单机部署的系统被演化成分布式集群系统后,由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的应用并不能提供分布式锁的能力。为了解决这个问题就需要一种跨机器的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题! 分布式锁应该具备哪些条件: 1、在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行;

Python 协程

白昼怎懂夜的黑 提交于 2019-11-29 13:51:07
协程 进程 :操作系统中存在 线程 :操作系统中存在 协程 :是微线程 模块(greenlet) 协程不是一个真实存在的东西,是由程序员创造出来的 协程,是对一个线程分片,使得线程在代码块之间进行来回切换,而不是原来逐步执行。 单纯的协程是无用的,有时候而且会降低性能 示例代码: import greenlet def f1(): print(11) gr2.switch() print(22) gr2.switch() def f2(): print(33) gr1.switch() print(44) # 创建两个协程 gr1 = greenlet.greenlet(f1) gr2 = greenlet.greenlet(f2) gr1.switch() 协程存在的意义 单线程实现并发:如果遇到 IO操作 就会进行切换 遇到IO就切换 + 协程 == 牛逼起来了。。。 遇到IO就切换 实现: gevent模块 gevent模块(IO切换+协程) 安装: pip install gevent 示例代码: ########### 协程+IO切换 from gevent import monkey monkey.patch_all() # 以后代码中遇到IO就会执行greenlet的switch进行切换 import requests import gevent def get

并发编程之多线程

耗尽温柔 提交于 2019-11-29 10:39:39
并发编程 并发(伪):由于执行速度特别快,人感觉不到 并行(真):创建10个人同时操作 线程 单进程,单线程的应用程序 print('666') 到底什么是线程?什么是进程 Python自己没有这玩意,Python中调用的操作系统的线程和进程(伪线程) 多线程 工作的最小单元 共享进程中所有资源 每个线程可以分担一点任务,最终完成最后的结果 python多线程原理:python的多线程实际是一个假的多线程(多个线程在1核CPU上运行,进行快速的切换导致错觉为同时执行) 代码 import threading def func(arg): print(arg) th = threading.Thread(target=func) th.start() print('end') 一个应用程序:软件 默认一个程序只有一个进程 可以有多个进程(默认只有一个),一个进程可以创建多个线程(默认一个)。 Python多线程情况下: 计算密集型操作:效率低(GIL锁) IO操作:效率高 Python多进程情况下: 计算密集型操作:效率高(浪费空间) IO操作:效率高(浪费资源) 以后写Python时: IO密集型用多线程:文件/输入输出/socket 计算密集型用多进程: 进程 独立开辟内存 进程之间的数据隔离 注意:进程是为了提供环境让线程工作 Python中线程和进程(GIL锁) GIL锁

python常见面试题

让人想犯罪 __ 提交于 2019-11-29 10:14:19
1、大数据的文件读取 利用生成器generator 迭代器进行迭代遍历:for line in file 2、迭代器和生成器的区别 迭代器是一个更加抽象的概念,任何对象,如果它的类有next方法和iter方法返回自身。对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数,iter()是Python的内置函数。iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。在没有后续元素时,next()会抛出一个StopIterration的异常。 生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在返回数据的时候需要使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值) 区别:生成器能做到迭代器能做的所有事,而且因为自动创建了__iter__()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保持程序状态的自动生成,当发生器终结时,还会自动跑出StopIterration异常。 3.装饰器的作用和功能 引入日志 函数执行时间统计 执行函数钱预备处理

Python线程1

匆匆过客 提交于 2019-11-29 08:11:38
#一个程序有多个进程,而一个进程可以有多个线程 ''' 提到了并发,那又不得不和并行作比较 并发是指在一段时间内同时做多个事情,比如在1点-2点洗碗、洗衣服等 而并行是指在同一时刻做多个事情,比如1点我左手画圆右手画方 两个很重要的区别就是“一段时间”和“同一时刻”.在操作系统中就是: 1)并发就是在单核处理中同时处理多个任务.(这里的同时指的是逻辑上的同时) 2)并行就是在多核处理器中同时处理多个任务.(这里的同时指的就是物理上的同时) 初学编程基本上都是单线程结构化编程,或者说是根本就接触不到线程这个概念 反正程序照着自己实现的逻辑,程序一步一步按照我们的逻辑去实现并且得到希望输出的结果 但随着编程能力的提高,以及应用场景的复杂多变,我们不得不要面临多线程并发编程 ''' import time ''' start=time.perf_counter() def worker(): print("worker") time.sleep(1) return; if __name__ == "__main__": for i in range(5): worker() end=time.perf_counter() print(end-start) 这是没有使用线程,程序最后用时5.1秒 输出为 worker worker worker worker worker 5.1 '''