python多线程并发

python进程池剖析(一)

不羁岁月 提交于 2020-02-23 13:44:09
  python中两个常用来处理进程的模块分别是subprocess和multiprocessing,其中subprocess通常用于执行外部程序,比如一些第三方应用程序,而不是Python程序。如果需要实现调用外部程序的功能,python的 psutil模块 是更好的选择,它不仅支持subprocess提供的功能,而且还能对当前主机或者启动的外部程序进行监控,比如获取网络、cpu、内存等信息使用情况,在做一些自动化运维工作时支持的更加全面。multiprocessing是python的多进程模块,主要通过启动python进程,调用target回调函数来处理任务,与之对应的是python的多线程模块threading,它们拥有类似的接口,通过定义multiprocessing.Process、threading.Thread,指定target方法,调用start()运行进程或者线程。   在python中由于 全局解释锁(GIL) 的存在,使用多线程,并不能大大提高程序的运行效率 【1】 。因此,用python处理并发问题时,尽量使用多进程而非多线程。并发编程中,最简单的模式是,主进程等待任务,当有新任务到来时,启动一个新的进程来处理当前任务。这种每个任务一个进程的处理方式,每处理一个任务都会伴随着一个进程的创建、运行、销毁,如果进程的运行时间越短,创建和销毁的时间所占的比重就越大

python 中的线程

我们两清 提交于 2020-02-22 16:05:04
线程的理解应该结合进程来对比理解更直接 如果我们操作系统当做一个工厂的话,那么创建一个进程就相当于在这个工厂里面新增了一个车间,车间里面存放了很多资源,而车间要运行起来很显然的标志就是流水线,而这些流水线就是线程,可以说线程是执行代码的最小单位。 而线程和进程两者在使用层面上有很大的相似性,所以开启或者说创建线程的2种方式跟创建进程很相似,区别在于导入的模块和类不一样而已。 一、开启线程方法: 第一种: from threading import Thread import time def task(name): time.sleep(2) print('%s has no jj' %name) if __name__ == '__main__': t=Thread(target=task,args=('JJ',)) t.start() print('主')  第二种: from threading import Thread import time class MyThread(Thread): def __init__(self, name): super().__init__() self.name = name def run(self): print("%s is running" % self.name) time.sleep(1) print("%s is done

python中的线程

放肆的年华 提交于 2020-02-22 16:04:43
线程的理解应该结合进程来对比理解更直接 如果我们操作系统当做一个工厂的话,那么创建一个进程就相当于在这个工厂里面新增了一个车间,车间里面存放了很多资源,而车间要运行起来很显然的标志就是流水线,而这些流水线就是线程,可以说线程是执行代码的最小单位。 而线程和进程两者在使用层面上有很大的相似性,所以开启或者说创建线程的2种方式跟创建进程很相似,区别在于导入的模块和类不一样而已。 一、开启线程方法: 第一种: from threading import Thread import time def task(name): time.sleep(2) print('%s has no jj' %name) if __name__ == '__main__': t=Thread(target=task,args=('JJ',)) t.start() print('主') 第二种: from threading import Thread import time class MyThread(Thread): def __init__(self, name): super().__init__() self.name = name def run(self): print("%s is running" % self.name) time.sleep(1) print("%s is done"

进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型

三世轮回 提交于 2020-02-19 07:11:28
一、paramiko模块 他是什么东西?   paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。 先来个实例: 1 import paramiko 2 # 创建SSH对象 3 ssh = paramiko.SSHClient() 4 5 # 允许连接不在know_hosts文件中的主机 6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 7 # 连接服务器 8 ssh.connect(hostname='10.0.0.31', port=52113, username='root', password='123456') 9 # 执行命令 10 stdin, stdout, stderr = ssh.exec_command('df') 11 # 获取命令结果 12 res,err = stdout.read(),stderr.read() 13 result = res if res else err 14 15 print(result.decode()) 16 17 # 关闭连接 18 ssh.close() 有些机智的少年会突然想到,如果我想做信任呢??我的秘钥怎么用在里面呢? 同样机智的我想到了下面的方法: 1 import

python-多线程(原理篇)

核能气质少年 提交于 2020-02-17 15:37:07
/*--> */ /*--> */ 多线程的基本概念 语言学习总是绕不过一些东西,例如多进程和多线程,最近越来越发现,上来看几个实例练习一下过几天就不知其所以然了。所以还是先看看原理,在看实例练习吧! 线程的概念 概念:线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。其实平时我们启动程序,其实是启动的进程,但是在往下细分的话,其实是进程的一个或者多个线程完成的功能。 好处 :(1)易于调度。 (2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。 (3)开销少。创建线程比创建进程要快,所需开销很少。 (4)利于充分发挥多处理器的功能。通过创建多线程进程,每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。 多线程vs多进程 操作系统会为每个进程分配不同的内存块,而多个线程共享进程的内存块。这带来最直接的不同就是创建线程的开销远小于创建进程的开销。 同时,由于内存块不同,所以进程之间的通信相对困难。而线程间的通信简单快速,就是共享进程内的全局变量。 但是,进程的调度由操作系统负责

Python_面试宝典_高级

两盒软妹~` 提交于 2020-02-16 14:18:40
python中的类方法、类实例方法、静态方法有什么区别? 类方法:是类对象的方法,在定义时需要在上方使用“@classmethod”进行装饰,形参为 cls 表示类对象,类对象和实例对象都可调用。 类实例方法:是类实例化对象的方法,只有实例对象可以调用,形参为 self ,指代对象本身 静态方法:是一个任意函数,在其上方使用“@staticmethod”进行装饰,可以用对象直接调用,静态方法实际上跟该类没有太大关系。 python函数调用的时候参数的传递方式是值传递还是引用传递? python的参数传递有:位置参数、默认参数、可变参数、关键字参数 函数的传值到底是值传递还是引用传递,要分情况: 不可变参数值传递:像整数和字符串这样的不可变对象,是通过拷贝进行传递的,因为你无论如何都不可能在原处改变不可变对象。 可变参数是引用传递的: 比如像列表,字典这样的对象是通过引用传递的、和c语言里面的指针传递数组很类似,可变对象能在函数内部改变。 对缺省参数的理解? 缺省参数指在调用函数的时候没有传入参数的情况下,调用默认的参数,在调用函数的同时赋值时,所传入的参数会代替默认参数。 *args 是不定长参数,它可以表述输入参数的不确定的,可以是任意多个 **kwargs 是关键字参数,赋值的时候是以 = 值的方式,参数是可以任意多对在定义函数的时候不确定会有多少参数会传入,就可以使用两个参数

线程,线程安全与python的GIL锁

别来无恙 提交于 2020-02-15 06:55:56
  今天看到一篇文章,讲述的是几个提升python性能的项目: 传送门   在看的过程中,接触到一个名词,一个从学python开始就一直看到,但是从来都是一知半解的名词,心里不开心,必须把它搞明白,对了,这个词就是 GIL。网上搜索了一些资料,粗浅的理解了什么是GIL,自己感觉学习的过程比较好,感觉略有收获,老规矩,为了巩固知识,自己整片文章出来写一写,其实好多文章已经写的很完善了,所以这篇随笔,只做知识巩固,如有雷同,请各位原创作者原谅,小菜鸟一枚,如果哪里写的有问题,还请各位前辈不吝指正。   一句话: 解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁。   首先,GIL的全名, Global Interpreter Lock ,鉴于英文水平,不做名词翻译,以免误导。大体解释一下,这个锁就是用来为了解决Cpython多线程中线程不安全问题引入的一个全局排它锁,它的作用就是在多线程情况下,保护共享资源,为了不让多个线程同时操作共享资源,导致不可预期的结果而加上的锁,在一个线程操作共享资源时,其他线程请求该资源,只能等待GIL解锁。这个设置在Cpython刚引入多线程概念的时候就有了,然后后续的各种包和组件开发都不可避免的受到了GIL的影响,所以有人会说,python在多线程处理的时候很慢。python GIL实现方式类似于如下伪代码: if __name__ == '_

python threading实例解析diaoyo'n

隐身守侯 提交于 2020-02-15 02:54:04
1.认识GIL: 说到GIL一直是代码专家们一直以来想要解决的问题,也是被许多程序员诟病的,下面带领大家看下官方threading模块document中如何去描述对于GIL这个全局解释器锁的: https://docs.python.org/3/library/threading.html 全局解释器锁 所使用的机制 的CPython 解释器来确保只有一个线程执行的Python 字节码 在一个时间。 通过使对象模型(包括关键的内置类型,例如 dict )隐式安全地防止并发访问 ,从而简化了CPython的实现 。 锁定整个解释器可以使解释器更容易进行多线程处理,但会牺牲多处理器机器提供的许多并行性。 但是,某些扩展模块(标准的或第三方的)被设计为在执行诸如压缩或散列之类的计算密集型任务时释放GIL。 另外,在执行I / O时,始终释放GIL。 过去创建“自由线程”解释器(一种以更精细的粒度锁定共享数据的解释器)的努力并未成功,因为在常见的单处理器情况下性能会受到影响。 相信克服该性能问题将使实施更加复杂,因此维护成本更高。 在这里专门对全局解释器锁的概念引入时说了这么一段话,第一指明了GIL造成了python解释器一次只有一个线程可以获取解释器锁,也就是解释器本身是自带锁的,谁先拿到谁就可以抢占到cpu的资源, 从而导致了python无论一个线程怎么去跑

Python中使用多进程来实现并行处理的方法小结

依然范特西╮ 提交于 2020-02-14 00:02:35
Python中使用多进程来实现并行处理的方法小结 进程和线程是计算机软件领域里很重要的概念,进程和线程有区别,也有着密切的联系,先来辨析一下这两个概念: 1.定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 2.关系 一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行. 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。 3.区别 进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。 简而言之,一个程序至少有一个进程

Python协程

江枫思渺然 提交于 2020-02-13 05:32:49
一、一些基本概念: 协程(Coroutine),又称微线程,纤程,一种用户级的轻量级线程。 栈(Stack)是一个数据集合,可以理解为只能在一端进行插入或删除操作的列表。 协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态。 在并发编程中,协程与线程类似,每个协程表示一个执行单元,有自己的本地数据,与其他协程共享全局数据和其他资源 协程需要用户自己来编写调度逻辑,对于CPU来说,协程其实是单线程,所以cpu不用去考虑怎么调度,切换上下文,这就省去了cpu的切换开销,所以协程一定程度上又好于多线程 协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。 协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程; 二、yield回顾: def f(): print('ok1') count=yield 5 print(count) print('ok2') yield 6 gen=f() # ret=next(gen) # print(ret) ret=gen