python多线程

什么时候用多线程什么时候用多进程呢?GUL

匿名 (未验证) 提交于 2019-12-03 00:13:02
那么在 Python 中什么时候用多线程什么时候用多进程呢?当在CPU-bound(计算密集型:绝大多数时间在计算) 时最好用 - 多进程, 而在 I/O bound(I/O密集型 : IO 处理 并且 大多时间是在等待) 的时候最好用 - 多线程。 python因为其全局解释器锁GIL而无法通过线程实现真正的平行计算。这个论断我们不展开,但是有个概念我们要说明,IO密集型 vs. 计算密集型。 IO密集型: 读取文件,读取网络套接字频繁。 计算密集型: 大量消耗CPU的数学与逻辑运算,也就是我们这里说的平行计算。 而concurrent.futures模块,可以利用multiprocessing实现真正的平行计算。 核心原理是:concurrent.futures会以子进程的形式,平行的运行多个python解释器,从而令python程序可以利用多核CPU来提升执行速度。由于子进程与主解释器相分离,所以他们的全局解释器锁也是相互独立的。每个子进程都能够完整的使用一个CPU内核。 来源:博客园 作者: 知是行之始,行是知之成 链接:https://www.cnblogs.com/rnanprince/p/11630119.html

协程基础及其创建和使用方法

匿名 (未验证) 提交于 2019-12-03 00:11:01
之前我们学习了线程、进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位。按道理来说我们已经算是把cpu的利用率提高很多了。但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程、创建线程、以及管理他们之间的切换。 随着我们对于效率的追求不断提高,基于单线程来实现并发又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。这样就可以节省创建线进程所消耗的时间。 所以,产生协程的概念是为了实现: 单线程下实现并发 为此我们需要先回顾下并发的本质:切换+保存状态。 多线程实现并发:cpu正在运行一个任务(线程),会在两种情况下切走去执行其他的任务(切换由操作系统强制控制):,一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长。 如果是做纯计算任务的切换,这种切换反而会降低效率。 先在串行下执行计算任务: import time def eat (): print ( 'eat 1' ) # 疯狂计算的时候没有io(计算密集) time . sleep ( 2 ) for i in range ( 100000000 ): i += 1 def play (): print ( 'play 1' ) # 疯狂的计算的时候没有io(计算密集) time . sleep ( 3 ) for i

线程同步锁、死锁、递归锁、信号量、GIL

匿名 (未验证) 提交于 2019-12-03 00:09:02
Ŀ¼ 所有线程同一时间读写同一个数据,有的线程已经对数据进行修改了,造成有的线程拿到的数据时旧的数据,而不是修改后的数据,造成结果不正确,于是引入了同步锁解决问题, 同步锁的原理是同一时间只能有一个线程读写数据。 锁通常被用来实现对共享资源的同步访问。从threading模块导入一个Lock类,为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其他线程已经获得了该锁,则当前线程需等待其被释放),待资源访问完后,再调用release方法释放锁。 下面这个例子就需要用到同步锁: from threading import Thread x = 0 def task(): global x for i in range(20000): x=x+1 # t1 的 x刚拿到0 保存状态 就被切了 # t2 的 x拿到0 进行+1 1 # t1 又获得运行了 x = 0 +1 1 # 思考:一共加了几次1? 加了两次1 真实运算出来的数字本来应该+2 实际只+1 # 这就产生了数据安全问题. if __name__ == '__main__': t1 = Thread(target=task) t2 = Thread(target=task) t3 = Thread(target=task) t1.start() t2.start() t3

商汤科技一面

匿名 (未验证) 提交于 2019-12-02 23:34:01
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/strivenoend/article/details/90381840 1介绍一下你的项目吧 2后端语言你用什么?? 3hr说你的csdn好像还不错? 4说一下你项目的增删改查,你通常都是什么思路去做项目的呢? 5数据库设计表结构,你怎么优化的,后期数据维护这你怎么做的? 如果数据量很大的话你怎么优化呢? 【数据量大如何处理】 优化顺序 第一,优化你的sql和索引;   想实现一个查询,可以写出很多种查询语句,不同的语句,根据你选择的引擎、表中数据的分布情况、索引情况、数据库优化策略、查询中的锁策略等因素,最终查询的效率相差很大;优化要从整体去考虑,有时你优化一条语句后,其它查询反而效率被降低了,所以要取一个平衡点。 第二,加缓存,memcached,redis; 第三,主从复制或主主复制,读写分离; 第四 ,先删,在汇总(这是面试官给出的idea) 第五,分库分表 【优化表结构】 很多人都将 数据库设计范式 作为数据库表结构设计“圣经”,认为只要按照这个范式需求设计,就能让设计出来的表结构足够优化,既能保证性能优异同时还能满足扩展性要求。殊不知,在N年前被奉为“圣经”的数据库设计3范式早就已经不完全适用了。这里我整理了一些比较常见的数据库表结构设计方面的优化技巧,希望对大家有用。

多线程爬虫

匿名 (未验证) 提交于 2019-12-02 22:56:40
说明: python这门语言在设计的时候,有一个全局解释器锁(GIL锁)这个就尴尬了,这个就导致了python的多线程都是伪多线程,也就是本质上还是一个线程 但是这个线程每个事情只做几毫秒,几毫秒以后就保存现场,换做其他事情,几毫秒以后再做其他事情, 微观上的单线程,宏观上就相当于同时,这个在(I/O)密集型上影响不大,但是在CPU密集型上影响很大,但是爬虫属于I/O密集型,所以采用多线程; 1,多进程的库(multiprocessing) 进程和进程之间不能直接共享内存和堆栈资源,并且启用进程开销较大,因此使用多线程要比使用多进程来做爬虫更加具备优势,multiprocessing下面有个 dummy的模块,他可以让python的线程使用multiprocessing的各种方法。 # -*- coding:UTF-8 -*- __autor__ = 'zhouli' __date__ = '2018/10/27 23:06' from multiprocessing.dummy import Pool def calc(num): return num * num pool = Pool(3) orign_num = [x for x in range(100)] result = pool.map(calc, orign_num) print(result) [0, 1, 4,

Python--多线程 threading

匿名 (未验证) 提交于 2019-12-02 22:56:40
简单使用 import threading def thread_job () : print ( 'This is a thread of %s' % threading . current_thread ()) def main () : thread = threading . Thread ( target = thread_job ,) # 定义线程 thread . start () # 让线程开始工作 thread . join () 可以使用的API 当前活跃线程数 threading . active _count () 查看所有线程信息 threading . enumerate () 查看当前运行的线程 threading . current _thread () join功能 thread.join() 表示 当前主线程要等待所有带 join的子线程结束以后才能接着执行。 用队列管理多线程返回结果的例子 import threading import time from queue import Queue def job ( l , q ) : for i in range ( len ( l )): l [ i ] = l [ i ]** 2 q . put ( l ) def multithreading () : q = Queue ()

Python多线程与多线程中join()的用法

匿名 (未验证) 提交于 2019-12-02 22:54:36
转载地址:https://www.cnblogs.com/cnkai/p/7504980.html Python多线程与多进程中join()方法的效果是相同的。 下面仅以多线程为例: 首先需要明确几个概念: 知识点一: 当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程,在python中,默认情况下(其实就是setDaemon(False)),主线程执行完自己的任务以后,就退出了,此时子线程会继续执行自己的任务,直到自己的任务结束,例子见下面一。 知识点二: 当我们使用setDaemon(True)方法,设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止,例子见下面二。 知识点三: 此时join的作用就凸显出来了,join所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程在终止,例子见下面三。 知识点四: join有一个timeout参数: 当设置守护线程时,含义是主线程对于子线程等待timeout的时间将会杀死该子线程,最后退出程序。所以说,如果有10个子线程,全部的等待时间就是每个timeout的累加和。简单的来说,就是给每个子线程一个timeout的时间,让他去执行,时间一到

铁乐学python_Day43_协程

匿名 (未验证) 提交于 2019-12-02 22:51:30
铁乐学python_Day43_协程 之前我们学习了线程、进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位。 按道理来说我们已经算是把cpu的利用率提高很多了。 但是我们知道无论是创建多进程还是创建多线程来解决问题, 都要消耗一定的时间来创建进程、创建线程、以及管理他们之间的切换。 随着我们对于效率的追求不断提高,基于单线程来实现并发又成为一个新的课题, 即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。 这样就可以节省创建线进程所消耗的时间。 为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制), 一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长。 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态。 运行、阻塞、就绪。 1、进程在运行状态下遇到io之类等待输入而进入阻塞状态; 2、调度程序选择另一个就绪状态中的进程; 3、调度程序选择就绪的进程转到运行状态; 4、之前阻塞状态下的进程出现有效输入后切换到就绪状态,而不能马上进入运行状态。 一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果, 如果多个任务都是纯计算的

python-进程

匿名 (未验证) 提交于 2019-12-02 22:51:30
进程: 一个运行起来的程序或者软件叫做进程   1.1 每次启动一个进程都向操作系统索要运行资源,进程是操作系统资源分配的基本单位   1.2默认情况下启动一个进程默认只有一条线程,这个线程主线程,线程是依附在进程里面,没有       进程就没有线程,进程可以有多个线程 进程和线程的对比:    进程:每次启动一个进程都需要向操作系统索要运行资源,进程是操作系统资源分配的基本单位   线程:执行代码的分支,线程是cpu调度的基本单位,线程是依附在进程里面的,没有进程就线程,默认一个进程只有一个线程,但是可以开辟多个线程。    进程不共享全局变量 ,线程共享全局变量但是要注意资源竞争数据错误的问题,可以使用线程同步或着互斥锁。   多进程开发比单进程多线程开发稳定性要强,因为某个进程死了不会影响其他进程的运行,但是单进程多线程开发,如果这个进程死了,那么进程中的所有线程都不能再运行了   多进程开发比单进程开发资源要分配得多,多线程可以利用进程中的资源,但是每次启动一个进程都需要向操作系统索要运行资源。   线程和进程在使用上各有优缺点:     线程执行开销小,但不利于资源的管理和保护;而进程正相反。 正常情况下主进程会等待所有的子进程执行完成以后程序再退出。 导入模块名 :import os (文件、目录操作)   os.getpid(): 获取当前进程的编号   os

python多线程建立代理ip池

匿名 (未验证) 提交于 2019-12-02 22:51:30
之前有写过用单线程建立代理ip池,但是大家很快就会发现,用单线程来一个个测试代理ip实在是太慢了,跑一次要很久才能结束,完全无法忍受。所以这篇文章就是换用多线程来建立ip池,会比用单线程快很多。之所以用多线程而不是多进程,是因为测试时间主要是花费在等待网络传递数据上,处理本地计算的时间很短,用多线程能更好地发挥单核性能,而且多线程开销比多进程开销小得多。当然,单核性能会有极限,如果想再提高性能就需要多进程和多线程混用了。当然这里说的是用CPython作为解释器时候的情况,因为绝大多数人用的都是CPython,所以以下说的都是这种情况。 受限于个人学识,对多进程和多线程的理解也不是很深刻,如果以后有机会会写写关于并发编程的文章。CPython因为GIL锁的原因,多线程无法发挥多核性能,但是可以用多进程来发挥多核性能。注意GIL锁不是python语言特性,只是CPython解释器的原因。任何python线程在执行前,都必须获得GIL锁,然后每执行100条字节码,解释器就自动释放GIL锁,让别的线程执行。所以python线程只能交替执行,即使有多个线程跑在多核CPU上,也只能利用一个核。 其实程序主体在之前的文章已经写好了,我们需要的只是稍微做点改进,以适合多线程编程。我的思路是,设置一个线程专门用来爬取待测试ip,其他线程获取待测试ip进行测试。这也是分布式编程的思想。