python自动化运维之路~DAY8
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.线程进程介绍
为了方便我们队线程和进程的理解,我们来画2组图,方便我们对python中的线程和进程的理解。
其他语言线程与进程的关系如下图:
python语言线程与进程的关系如下图:
1.计算机工作最小单元是线程;
2.启动一个python可执行文件->应用程序->最少要有一个进程>最少要一有一个线程
3.应用场景:
a>.IO密集型:线程
b>.计算密集型:进程
4.GIL,全局解释器所。
功能:保证同一个进程中只有一个线程同时被调用。(以上三点是所有语言的共同之处,只是PYTHON多了一个GIL规则而已。)
二.线程
1.线程的基本使用
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import threading #引入线程模块 7 import time #引入时间模块 8 9 def test(arg): 10 time.sleep(1) #执行该函数的时候让其睡上1s 11 print(arg) #打赢传进来的位置参数 12 13 for i in range(10): 14 t = threading.Thread(target=test,args=[i,]) #定义一个线程,并将2个值传进去; 15 t.start() #启动该进程,标志着这个进程为准备状态,随时等待CPU执行。 16 17 print("我是主线程") #主线程 18 19 20 #以上代码执行结果如下: 21 我是主线程 22 3 23 2 24 0 25 4 26 8 27 7 28 6 29 1 30 5 31 9 32 33 #经过试验证明,本来应该10s才能结束的脚本,但是用多线程运行的话只需要2s左右的时间就能搞定这个脚本,效率的确提高的不少!
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import threading #引入线程模块 7 import time #引入时间模块 8 9 def test(arg): 10 time.sleep(arg) 11 print(arg) 12 13 for i in range(10): 14 t = threading.Thread(target=test,args=[i,]) #定义一个线程,并将2个值传进去; 15 #t.setDaemon(True) #主线程终止,不等待子线程,下面与其相反。 16 t.setDaemon(False) #主线程终止,等待子线程,默认是需要等待的,所以这一行不写也可以。 17 t.start() #启动该进程,标志着这个进程为准备状态,随时等待CPU执行。 18 t.join(2) #等待第一个线程执行完毕后再进行下一次循环,里面的参数表示等待的最大时间,如果不写的话就会一直等待当前循环的线程执行完毕后后再进行下一次循环,我们可以理解为等待最大时间。我这里让其最多等待2s的时间。 19 20 print("我是主线程") #主线程 21 22 #以上代码执行结果如下: 23 0 24 1 25 2 26 3 27 4 28 5 29 6 30 我是主线程 31 7 32 8 33 9
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from threading import Thread 7 8 def task(num,list): 9 list.append(num) 10 print(list) 11 12 if __name__ == '__main__': 13 v = [] 14 for i in range(10): 15 p = Thread(target=task,args=(i,v)) 16 p.start()
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import threading #导入线程模块 7 import time 8 9 class MyThread(threading.Thread): #继承了threading.Thread方法 10 def __init__(self,func,*args,**kwargs): 11 super(MyThread,self).__init__(*args,*kwargs) #实例化MyThread函数,也就是实例化它自己。 12 self.func = func 13 def run(self): 14 self.func(5) #传递的参数是5,意思是一会会睡5s 15 16 def task(arg): #这个函数最最终被MyThread方法调用. 17 print("其实调用MyThread就是调用run方法哟~") 18 time.sleep(arg) 19 print("程序运行结束") 20 21 obj = MyThread(func=task) #实例化 22 obj.start() 23 24 25 26 #以上代码执行结果如下: 27 其实调用MyThread就是调用run方法哟~ 28 程序运行结束
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import threading #导入线程模块 7 import time 8 ''' 9 前言: 10 我们在网上买商品的时候,卖家都有库存,当我们订单一个商品的时候就会让库存自减一,但是如果多个用户同时点击, 11 涉及到并发的时候,就需要对这个数据进行锁定,这一点尤其是在mysql数据库中尤为体现。那么它是如何实现的呢? 12 ''' 13 stock = 10 #定义库存还剩下10件 14 lock = threading.Lock() #设定一个锁 15 16 def task(arg): 17 time.sleep(2) 18 lock.acquire() #申请使用锁,其他人得排队等待。 19 global stock #由于修改的是全局变量,需要用global方法声明一下 20 stock -= 1 21 print(stock) 22 lock.release() #释放锁 23 24 for i in range(10): 25 t = threading.Thread(target=task,args=(i,)) 26 t.start() 27 28 29 #以上代码执行结果如下: 30 9 31 8 32 7 33 6 34 5 35 4 36 3 37 2 38 1 39 0
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import threading #导入线程模块 7 import time 8 ''' 9 前言: 10 我们在网上买商品的时候,卖家都有库存,当我们订单一个商品的时候就会让库存自减一,但是如果多个用户同时点击, 11 涉及到并发的时候,就需要对这个数据进行锁定,这一点尤其是在mysql数据库中尤为体现。那么它是如何实现的呢? 12 ''' 13 stock = 10 #定义库存还剩下10件 14 #lock = threading.Lock() 15 lock = threading.RLock() #设定一个递归锁 16 def task(arg): 17 time.sleep(2) 18 lock.acquire() #锁一次 19 lock.acquire() #再锁一次 20 global stock #由于修改的是全局变量,需要用global方法声明一下 21 stock -= 1 22 print(stock) 23 lock.release() #开第一层锁 24 lock.release() #再开一层锁,要注意的是,只有Rlock才有递归解锁的功能,但是lock却没有这个功能,一点用lock被锁住2次,那么就会被彻底锁住。 25 26 for i in range(10): 27 t = threading.Thread(target=task,args=(i,)) 28 t.start() 29 30 31 #以上代码执行结果如下: 32 9 33 8 34 7 35 6 36 5 37 4 38 3 39 2 40 1 41 0
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import threading #导入线程模块 7 import time 8 ''' 9 前言: 10 我们在网上买商品的时候,卖家都有库存,当我们订单一个商品的时候就会让库存自减一,但是如果多个用户同时点击, 11 涉及到并发的时候,就需要对这个数据进行锁定,这一点尤其是在mysql数据库中尤为体现。那么它是如何实现的呢? 12 ''' 13 stock = 20 #定义库存还剩下20件 14 lock = threading.BoundedSemaphore(5) #表示同时能有5个人可以解开这个锁 15 def task(arg): 16 17 lock.acquire() #锁一次 18 time.sleep(1) 19 global stock #由于修改的是全局变量,需要用global方法声明一下 20 stock -= 1 21 print(stock) 22 lock.release() #开第一层锁 23 24 for i in range(20): 25 t = threading.Thread(target=task,args=(i,)) 26 t.start() 27 28 29 #以上代码执行结果如下: 30 19 31 18 32 17 33 16 34 15 35 14 36 13 37 12 38 11 39 10 40 9 41 8 42 7 43 6 44 5 45 4 46 3 47 2 48 1 49 0
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import threading #导入线程模块 7 import time 8 ''' 9 前言: 10 我们在网上买商品的时候,卖家都有库存,当我们订单一个商品的时候就会让库存自减一,但是如果多个用户同时点击, 11 涉及到并发的时候,就需要对这个数据进行锁定,这一点尤其是在mysql数据库中尤为体现。那么它是如何实现的呢? 12 ''' 13 lock = threading.Event() #创建一把事件锁 14 15 def task(arg): 16 time.sleep(1) 17 lock.wait() #锁住所有的线程 18 print(arg) 19 20 for i in range(10): 21 t = threading.Thread(target=task,args=(i,)) 22 t.start() 23 24 while True: 25 value = input("please enter something>>>:") 26 if value == "1": 27 lock.set() #开锁,将之前用“lock.wait()”锁定的线程全部解开! 28 # lock.clear() #其实功能和"lock.set()"都标记而已,"lock.set()"表示可以开锁,而"lock.set()"表示锁定,所以默认情况下使用的就是"lock.set()"! 29 30 31 #以上代码执行结果如下: 32 please enter something>>>:1 33 please enter something>>>:5 34 1 35 9 36 3 37 7 38 2 39 0 40 4 41 8 42 6
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import threading #导入线程模块 7 import time 8 ''' 9 前言: 10 我们在网上买商品的时候,卖家都有库存,当我们订单一个商品的时候就会让库存自减一,但是如果多个用户同时点击, 11 涉及到并发的时候,就需要对这个数据进行锁定,这一点尤其是在mysql数据库中尤为体现。那么它是如何实现的呢? 12 ''' 13 lock = threading.Condition() #创建随机锁 14 15 def task(arg): 16 time.sleep(1) 17 lock.acquire() 18 lock.wait() #锁住所有的线程 19 print('线程:',arg) #被锁定的代码 20 lock.release() 21 for i in range(10): 22 t = threading.Thread(target=task,args=(i,)) 23 t.start() 24 25 while True: 26 value = input("please enter something>>>:") 27 lock.acquire() 28 lock.notify(int(value)) 29 lock.release() 30 31 32 33 #以上代码执行结果如下: 34 please enter something>>>:1 35 please enter something>>>:线程: 1 36 2 37 please enter something>>>:线程: 2 38 线程: 0 39 3 40 please enter something>>>:线程: 3 41 线程: 4 42 线程: 5 43 4 44 please enter something>>>:线程: 7 45 线程: 8 46 线程: 9 47 线程: 6 48 5 49 please enter something>>>:6 50 please enter something>>>:
4.线程池
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor 7 import time 8 import requests #需要安装request模块,在windows的cmd窗口上执行:“C:\Users\尹正杰>pip3 install requests”即可。 9 10 pool = ThreadPoolExecutor(2) #创建一个进程池,允许最大连接数为2 11 12 def task(url): 13 response = requests.get(url) 14 print('统计网站的字节数为:',url,len(response.content)) 15 16 url_list = [ 17 'http://www.cnblogs.com/yinzhengjie/', 18 'http://www.autohome.com.cn', 19 'http://www.baidu.com', 20 'http://www.sobaidupan.com/' 21 ] 22 23 for url in url_list: 24 print('开始请求链接',url) 25 # 去连接池中获取链接 26 pool.submit(task,url) 27 28 29 #以上代码执行结果如下: 30 开始请求链接 http://www.cnblogs.com/yinzhengjie/ 31 开始请求链接 http://www.autohome.com.cn 32 开始请求链接 http://www.baidu.com 33 开始请求链接 http://www.sobaidupan.com/ 34 统计网站的字节数为: http://www.cnblogs.com/yinzhengjie/ 33024 35 统计网站的字节数为: http://www.baidu.com 2381 36 统计网站的字节数为: http://www.autohome.com.cn 1094712 37 统计网站的字节数为: http://www.sobaidupan.com/ 68175
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor 7 import time 8 import requests #需要安装request模块,在windows的cmd窗口上执行:“C:\Users\尹正杰>pip3 install requests”即可。 9 10 """ 11 def task(host): 12 import paramiko 13 ssh = paramiko.SSHClient() 14 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 15 ssh.connect(hostname=host, port=22, username='yinzhengjie', password='123') 16 stdin, stdout, stderr = ssh.exec_command('df') 17 result = stdout.read() 18 ssh.close() 19 print(result) 20 pool = ThreadPoolExecutor(2) 21 host_list = [ 22 'c1.com', 23 'c2.com', 24 'c3.com', 25 ] 26 for host in host_list: 27 print('开始请求',host) 28 # 去连接池中获取链接 29 pool.submit(task,host) 30 """ 31 def txt(future): 32 download_response = future.result() 33 print('处理中',download_response.url,download_response.status_code) 34 def download(url): 35 response = requests.get(url) 36 return response # response包含了下载的所有内容 37 pool = ThreadPoolExecutor(2) 38 url_list = [ 39 'http://www.cnblogs.com/yinzhengjie/', 40 'http://www.autohome.com.cn', 41 'http://www.baidu.com', 42 'http://www.sobaidupan.com/', 43 ] 44 for url in url_list: 45 # 去连接池中获取链接 46 # 去下载吧 47 print('开始请求',url) 48 future = pool.submit(download,url) 49 # 下载完成之后,执行txt函数 50 future.add_done_callback(txt) 51 52 53 #以上代码执行结果如下: 54 开始请求 http://www.cnblogs.com/yinzhengjie/ 55 开始请求 http://www.autohome.com.cn 56 开始请求 http://www.baidu.com 57 开始请求 http://www.sobaidupan.com/ 58 处理中 http://www.cnblogs.com/yinzhengjie/ 200 59 处理中 http://www.baidu.com/ 200 60 处理中 http://www.autohome.com.cn/beijing/ 200 61 处理中 http://www.sobaidupan.com/ 200
三.进程
1.进程的基本使用
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from multiprocessing import Process #导入进程模块 7 import time 8 9 def task(arg): 10 time.sleep(5) 11 print(arg) 12 13 if __name__ == '__main__': 14 for i in range(10): 15 p = Process(target = task, args = (i,)) 16 p.daemon = True #主线程执行完毕时,不等待子进程执行完毕就终止程序,下面与其相反。如果不设置的话默认为False! 17 #p.daemon = False 18 p.start() 19 p.join(2) #每次循环等待子进程的执行时间为2s 20 print("我是主进程") #主进程 21 22 23 #以上代码执行结果如下:(我们会发现当主进程执行完毕后,子进程就停止了,这都归功于“p.daemon = True”) 24 0 25 1 26 2 27 3 28 4 29 5 30 6 31 7 32 我是主进程
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from multiprocessing import Process 7 8 def task(num,list): 9 list.append(num) 10 print(list) 11 12 if __name__ == '__main__': 13 v = [] 14 for i in range(10): 15 p = Process(target=task,args=(i,v)) 16 p.start() 17 18 #以上代码执行结果如下: 19 [1] 20 [0] 21 [2] 22 [3] 23 [4] 24 [5] 25 [6] 26 [7] 27 [8] 28 [9]
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from multiprocessing import Process,Array #调用类似C语音中的Array,其实就是定义一个数组。 7 8 def task(num,list_1): 9 list_1[num] = 1 10 print(list(list_1)) 11 12 if __name__ == '__main__': 13 v = Array('i',10) #里面的参数对应的是“数据类型”和“长度”,所以其中的“i”这个“v”变量就是为了验证进程与进程之间的共享。 14 for i in range(10): 15 p = Process(target=task,args=(i,v)) #调用task函数并将“i”和"v"两个变量传递给task函数。 16 p.start() 17 18 19 #以上代码执行结果如下: 20 [0, 1, 0, 0, 0, 0, 0, 0, 0, 0] 21 [0, 1, 0, 1, 0, 0, 0, 0, 0, 0] 22 [1, 1, 0, 1, 0, 0, 0, 0, 0, 0] 23 [1, 1, 0, 1, 1, 0, 0, 0, 0, 0] 24 [1, 1, 1, 1, 1, 0, 0, 0, 0, 0] 25 [1, 1, 1, 1, 1, 1, 0, 0, 0, 0] 26 [1, 1, 1, 1, 1, 1, 0, 1, 0, 0] 27 [1, 1, 1, 1, 1, 1, 1, 1, 0, 0] 28 [1, 1, 1, 1, 1, 1, 1, 1, 1, 0] 29 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from multiprocessing import Process,Manager #其中“Manager”是基于socket实现数据共享的。 7 8 def task(num,list_1): 9 list_1.append(num) 10 print(list_1) 11 12 if __name__ == '__main__': 13 v = Manager().list() 14 #v = Manager().dict() 15 for i in range(10): 16 p = Process(target=task,args=(i,v)) #调用task函数并将“i”和"v"两个变量传递给task函数。 17 p.start() 18 p.join() #不建议用join方法,进程还是变成了串行执行了,因为不用join的话会报错,无坑方便看到实现效果用join方法实现。 19 20 21 #以上代码执行结果如下: 22 [0] 23 [0, 1] 24 [0, 1, 2] 25 [0, 1, 2, 3] 26 [0, 1, 2, 3, 4] 27 [0, 1, 2, 3, 4, 5] 28 [0, 1, 2, 3, 4, 5, 6] 29 [0, 1, 2, 3, 4, 5, 6, 7] 30 [0, 1, 2, 3, 4, 5, 6, 7, 8] 31 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3.进程池
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from concurrent.futures import ProcessPoolExecutor #进程池和线程是都在concurrent这个模块里面 7 8 def task(arg): 9 print(arg) 10 return arg + 100 11 def call(arg): 12 data = arg.result() 13 print(data) 14 if __name__ == '__main__': 15 pool = ProcessPoolExecutor(5) 16 for i in range(10): 17 obj = pool.submit(task,i) 18 obj.add_done_callback(call) 19 20 21 #以上代码执行结果如下: 22 0 23 1 24 2 25 3 26 4 27 5 28 100 29 101 30 102 31 103 32 104 33 105 34 6 35 7 36 106 37 9 38 107 39 8 40 109 41 108
四.协程
首先,明确一点,协程在计算机是不存在的,它不像线程和进程那样,在计算机中我们可以实际创建出来的东西!携程本质上就是一个线程(它可以将一根线程的工作效率发挥到极致。),只不过它可以让这个线程中的代码不依次执行,也就是说它可以来回切换一个线程中的代码,比如执行第一个函数的第一行代码突然跳到第三个函数的第一行代码,一会又跳到第四个函数的第二行代码,然后又跳转到第一行中的代码继续执行...。实现协程也有现成的模块,叫:greenlet,协程适合处理IO操作,单独执行一个协程其实没有任何意义的。
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 ''' 7 扩展: 8 Greenlet是python的一个C扩展,来源于Stackless python,旨在提供可自行调度的‘微线程’, 即协程。generator 9 实现的协程在yield value时只能将value返回给调用者(caller)。 而在greenlet中,target.switch(value)可以切换到 10 指定的协程(target), 然后yield value。greenlet用switch来表示协程的切换,从一个协程切换到另一个协程需要显式 11 指定。 12 ''' 13 from greenlet import greenlet #需要安装模块,如果在linux环境中,我们打开cmd窗口执行:pip3 intsll greenlet即可。 14 def test1(): 15 print("我是第一行",100) 16 gr2.switch() 17 print("我是第二行",200) 18 gr2.switch() 19 20 def test2(): 21 print("I'm the first line",300) 22 gr1.switch() 23 print("I'm the second line",400) 24 25 gr1 = greenlet(test1) #创建一个‘微线程’,即协程,并不会有任何的输出。 26 gr2 = greenlet(test2) 27 gr1.switch() #“greenlet”用“switch”进行协程的切换 28 29 30 31 #以上代码执行结果如下: 32 我是第一行 100 33 I'm the first line 300 34 我是第二行 200 35 I'm the second line 400
协程也可以进行的二次加工,你可以对他自定义也可以用现成的gevent模块来实现。
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 from gevent import monkey; monkey.patch_all() 7 import gevent #需要安装模块,在cmd窗口运行“pip3 install greenlet”即可。 8 import requests 9 10 def f(url): 11 response = requests.get(url) 12 print(response.url,response.status_code) 13 14 gevent.joinall([ 15 gevent.spawn(f, 'http://www.cnblogs.com/yinzhengjie'), 16 gevent.spawn(f, 'http://www.baidu.com/'), 17 gevent.spawn(f, 'http://github.com/'), 18 ]) 19 20 #以上代码执行结果如下: 21 http://www.baidu.com/ 200 22 http://www.cnblogs.com/yinzhengjie 200 23 https://github.com/ 200
五.自定义异步非阻塞的框架。