lesson16-进程池和线程池
#视频1-讲解
#mysql 3306
#redis 6379
#mongodb 27017
阿里云服务器-了解下
22分钟://配置虚拟机脚本
bash install.sh
---------------------------------------------------------
#视频2-可以重复使用的线程
pyspider-对window不太友好,最好用ubuntu
//16重复使用线程1.py:
1 from threading import Thread 2 from queue import Queue 3 import time 4 5 #消费者 6 class MyThread(Thread): 7 def __init__(self): 8 super().__init__() 9 self.queue = Queue() # 创建一个Queue 10 self.daemon = True # 设置为守护进程 11 self.start() # 实例化的时候就直接启动线程 12 13 def run(self): 14 while True: 15 task, args, kwargs = self.queue.get() # 去队列里面拿任务与参数 16 task(*args, **kwargs) #执行任务 17 self.queue.task_done() # 计数器-1, 18 19 #用来向队列中提交数据 20 def apply_async(self, task, *args, **kwargs): 21 self.queue.put((task, args, kwargs)) 22 23 def MyThread_join(self): 24 self.queue.join() #阻塞,直到队列中没有数据,用计数器来判断 25 26 27 def func1(): 28 time.sleep(2) 29 print('任务一完成') 30 31 32 def func2(*args, **kwargs): 33 time.sleep(4) 34 print('任务二完成', args, '\n', kwargs) 35 36 #主线程充当生产者 37 t = MyThread() 38 t.apply_async(func1) # 主进程通过这个函数去把任务丢进去 39 t.apply_async(func2, args=(1, 2), kwargs={'a': 3, 'b': 4}) 40 41 print('任务提交完成') 42 t.MyThread_join() # 等待不会杀死守护线程 43 44 print('任务完成')
#运行:
任务提交完成
任务一完成
任务二完成 ()
{'args': (1, 2), 'kwargs': {'a': 3, 'b': 4}}
任务完成
---------------------------------------------------------
#视频3-实现简单的线程池
//16简单线程池2.py:
1 from threading import Thread 2 from queue import Queue 3 import time 4 5 #简单线程池,任务几乎同时完成 6 class ThreadPool: 7 def __init__(self, n): 8 self.queue = Queue() 9 #循环创建4个线程并开启 10 for i in range(n): 11 Thread(target=self.worker, daemon = True).start() 12 13 def worker(self): 14 while True: 15 func, args, kwargs = self.queue.get() 16 func(*args, **kwargs) 17 self.queue.task_done() 18 19 def apply_async(self, func, *args,**kwargs): 20 self.queue.put((func, args, kwargs)) 21 22 def join(self): 23 self.queue.join() 24 25 def task1(): 26 time.sleep(2) 27 print('任务一完成') 28 29 def task2(*args, **kwargs): 30 time.sleep(2) 31 print('任务二完成', args, '\n', kwargs) 32 33 34 pool = ThreadPool(2) 35 pool.apply_async(task1) 36 pool.apply_async(task2, args = (1,2), kwargs = {'a':3, 'b':4}) 37 38 print('任务提交完成') 39 pool.join() 40 print('任务完成')
#运行:
任务提交完成
任务一完成
任务二完成 ()
{'args': (1, 2), 'kwargs': {'a': 3, 'b': 4}}
任务完成
//16内置进程线程池3.py:
1 from multiprocessing.pool import ThreadPool 2 import time 3 4 def task1(): 5 time.sleep(2) 6 print('任务一完成') 7 8 def task2(*args,**kwargs): 9 time.sleep(2) 10 print('任务二完成',args,'\n',kwargs) 11 12 pool =ThreadPool(2) #内置线程池 13 pool.apply_async(task1) 14 pool.apply_async(task2,args=(1,2),kwds={'a':1,'b':2}) 15 print('任务提交完成') 16 pool.close() #要求,在join之前必须close,就不运行在提交任务了 17 pool.join() 18 print('任务完成')
#运行:
任务提交完成
任务一完成
任务二完成 (1, 2)
{'a': 1, 'b': 2}
任务完成
--------------------------------------------------------
1 from multiprocessing import Pool #进程池 2 import time 3 4 def task1(): 5 time.sleep(1) 6 print('任务一完成') 7 8 def task2(*args,**kwargs): 9 time.sleep(4) 10 print('任务二完成',args,'\n',kwargs) 11 12 #if __name__ == '__main__' #必须要有一个main 13 pool =Pool(4) #内置进程池 14 pool.apply_async(task1) 15 pool.apply_async(task2,args=(1,2),kwds={'a':1,'b':2}) 16 print('任务提交完成') 17 pool.close() #要求,在join之前必须close,就不运行在提交任务了 18 19 20 time.sleep(2) 21 pool.terminate() #中止进程池,中止所有任务 22 # pool.join() #等待所有子进程任务做完 23 print('任务完成')
#运行:
任务提交完成
任务一完成
任务完成
---------------------------------------------------------
#视频4-课件休息-拆包用法
1 #例子3 解包 2 3 def func(a,*args,**kwargs): 4 print(args) 5 print('解包',*args) 6 print(kwargs) 7 8 func(11111,(1,2),{'a':11,'b':22})
#运行:
((1, 2), {'b': 22, 'a': 11})
解包 (1, 2) {'b': 22, 'a': 11}
{}
--------------------------------------------------------
#视频5-用池来实现并发服务器
//16自带池并发server4.py:
1 from multiprocessing.pool import ThreadPool 2 import socket 3 4 server = socket.socket() 5 server.bind(('127.0.0.1', 8080)) 6 server.listen(100) 7 8 def worker(connection): 9 while True: 10 recv_data = connection.recv(1024) 11 if recv_data: 12 print('收到的数据:', recv_data.decode()) 13 connection.send(recv_data) 14 else: 15 print('客户端断开连接') 16 connection.close() 17 break 18 19 if __name__ == '__main__': 20 pool = ThreadPool(2) #线程池 2个 21 while True: 22 connection, address = server.accept() 23 print('客户端{}连接'.format(address)) 24 pool.apply_async(worker, args=(connection, )) 25 26
#运行:
server:
客户端('127.0.0.1', 40110)连接
客户端('127.0.0.1', 40112)连接
客户端('127.0.0.1', 40114)连接
收到的数据: hhh111
收到的数据: hhh2222
收到的数据: hhh3333
客户端('127.0.0.1', 40116)连接
收到的数据: 4444
客户端断开连接
client1:
请输入你要发送的数据:hhh111
hhh111
收到数据: hhh111
client2:
请输入你要发送的数据:hhh2222
hhh2222
收到数据: hhh2222
client3:
请输入你要发送的数据:4444
4444
收到数据: 4444
请输入你要发送的数据:quit
quit
自quit断开连接
---------------------------------------------------------
//16进程池线程池并发server5.py:
1 from multiprocessing import Pool, cpu_count 2 from multiprocessing.pool import ThreadPool 3 import socket 4 5 #print(cpu_count()) #cpu个数 6 server = socket.socket() 7 server.bind(('127.0.0.1', 8080)) 8 server.listen(1000) 9 10 11 def worker_thread(connection): 12 while True: 13 recv_data = connection.recv(1024) 14 if recv_data: 15 print(recv_data) 16 connection.send(recv_data) 17 else: 18 print('用户退出') 19 connection.close() 20 break 21 22 def worker_process(server): 23 thread_pool = ThreadPool( cpu_count()*2 ) #通常分配2倍CPU个数的线程 24 while True: 25 conncetion, remote_address = server.accept() #生成对等套接字 26 print('客户端{}连接'.format(remote_address)) 27 thread_pool.apply_async(worker_thread, args=(conncetion,)) 28 29 if __name__ == '__main__': 30 n = cpu_count() #打印当前电脑的cpu核数 31 process_pool = Pool(n) 32 for i in range(n): #充分利用CPU,为每一个CPU分配一个进程 33 process_pool.apply_async(worker_process, args=(server,)) 34 #把server丢到两个进程里面 35 36 process_pool.close() 37 process_pool.join() 38
#运行:
server:
客户端('127.0.0.1', 40118)连接
客户端('127.0.0.1', 40120)连接
b'helllo'
b'world'
用户退出
client1:
请输入你要发送的数据:helllo
helllo
收到数据: helllo
client2:
请输入你要发送的数据:world
world
收到数据: world
请输入你要发送的数据:quit
quit
自quit断开连接
---------------------------------------------------------
#视频6-总结+作业
用池实现并发服务器