ネットワークプログラミングのプロセスプールとスレッドプール
まず、プロセスプールとスレッドプール
ただ、マルチプロセスまたはマルチスレッドを学ぶためにソケット通信を開始するとき、我々は、複数またはマルチスレッドに基づく並行プロセスを実装するのを待つことはできませんが、この実装は致命的な欠陥である:プロセスやスレッドのサービス番号を開くとなりますクライアント側の同時増加と増加し、サーバー途方もない圧力をホストする、とさえ圧倒され、麻痺の数なので、我々はプロセスまたはスレッドの数のサービス側をオンに制御する必要が、それはでマシンを聞かせすることができます手頃な価格の範囲の操作内で、このようなプロセスプールとしてプロセスプールまたはスレッドプールの使用は、プールは本質的に、それはマルチプロセスに基づいて、プロセスを格納するために使用されるが、制限と相まってオープンプロセスの数です。
はじめに:
官网:https://docs.python.org/dev/library/concurrent.futures.html
concurrent.futures模块提供了高度封装的异步调用接口
ThreadPoolExecutor:线程池,提供异步调用
ProcessPoolExecutor: 进程池,提供异步调用
Both implement the same interface, which is defined by the abstract Executor class.
基本的な方法:
1、submit(fn, *args, **kwargs)
异步提交任务
2、map(func, *iterables, timeout=None, chunksize=1)
取代for循环submit的操作
3、shutdown(wait=True)
相当于进程池的pool.close()+pool.join()操作
wait=True,等待池内所有任务执行完毕回收完资源后才继续
wait=False,立即返回,并不会等待池内的任务执行完毕
但不管wait参数为何值,整个程序都会等到所有任务执行完毕
submit和map必须在shutdown之前
4、result(timeout=None)
取得结果
5、add_done_callback(fn)
回调函数
第二に、プロセスプール
はじめに:
1、The ProcessPoolExecutor class is an Executor subclass that uses a pool of processes to execute calls asynchronously. ProcessPoolExecutor uses the multiprocessing module, which allows it to side-step the Global Interpreter Lock but also means that only picklable objects can be executed and returned.
2、class concurrent.futures.ProcessPoolExecutor(max_workers=None, mp_context=None)
3、An Executor subclass that executes calls asynchronously using a pool of at most max_workers processes. If max_workers is None or not given, it will default to the number of processors on the machine. If max_workers is lower or equal to 0, then a ValueError will be raised.
使用法:
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import os,time,random
def task(n):
print('%s is runing' %os.getpid())
time.sleep(random.randint(1,3))
return n**2
if __name__ == '__main__':
executor=ProcessPoolExecutor(max_workers=3)
futures=[]
for i in range(11):
future=executor.submit(task,i)
futures.append(future)
executor.shutdown(True)
print('+++>')
for future in futures:
print(future.result())
第三に、スレッドプール
はじめに:
1、ThreadPoolExecutor is an Executor subclass that uses a pool of threads to execute calls asynchronously.
2、class concurrent.futures.ThreadPoolExecutor(max_workers=None, thread_name_prefix='')
3、An Executor subclass that uses a pool of at most max_workers threads to execute calls asynchronously.
4、Changed in version 3.5: If max_workers is None or not given, it will default to the number of processors on the machine, multiplied by 5, assuming that ThreadPoolExecutor is often used to overlap I/O instead of CPU work and the number of workers should be higher than the number of workers for ProcessPoolExecutor.
5、New in version 3.6: The thread_name_prefix argument was added to allow users to control the threading.Thread names for worker threads created by the pool for easier debugging.
使用法:
把ProcessPoolExecutor换成ThreadPoolExecutor,其余用法全部相同
四、マップ・メソッド
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import os,time,random
def task(n):
print('%s is runing' %os.getpid())
time.sleep(random.randint(1,3))
return n**2
if __name__ == '__main__':
executor=ThreadPoolExecutor(max_workers=3)
# for i in range(11):
# future=executor.submit(task,i)
executor.map(task,range(1,12)) #map取代了for+submit
第五に、コールバック関数
プロセスまたはスレッドプールの各プロセスやスレッドプールは、タスクが実装プロセスやスレッドを終了したときに自動的にトリガ機能を結合し、そしてパラメータとして、タスクの戻り値を受け取ることができ、関数がコールバック関数と呼ばれています。
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
from multiprocessing import Pool
import requests
import json
import os
def get_page(url):
print('<进程%s> get %s' %(os.getpid(),url))
respone=requests.get(url)
if respone.status_code == 200:
return {'url':url,'text':respone.text}
def parse_page(res):
res=res.result()
print('<进程%s> parse %s' %(os.getpid(),res['url']))
parse_res='url:<%s> size:[%s]\n' %(res['url'],len(res['text']))
with open('db.txt','a') as f:
f.write(parse_res)
if __name__ == '__main__':
urls=[
'https://www.baidu.com',
'https://www.python.org',
'https://www.openstack.org',
'https://help.github.com/',
'http://www.sina.com.cn/'
]
p=ProcessPoolExecutor(3)
for url in urls:
p.submit(get_page,url).add_done_callback(parse_page) #parse_page拿到的是一个future对象obj,需要用obj.result()拿到结果