ฉันจะไม่เรียกconcurrent.futures
"ขั้นสูง" เพิ่มเติม - เป็นอินเทอร์เฟซที่เรียบง่ายซึ่งทำงานได้เหมือนกันโดยไม่คำนึงว่าคุณจะใช้หลายเธรดหรือหลายกระบวนการเป็นกลไกการขนานแบบขนาน
ดังนั้นเหมือนแทบทุกกรณีของ "อินเตอร์เฟซที่เรียบง่าย" มากเหมือนกันไม่ชอบการค้ามีส่วนร่วม: มันมีเส้นโค้งการเรียนรู้ตื้นส่วนใหญ่เพียงเพราะมีมากน้อยลงที่จะต้องเรียนรู้; แต่เนื่องจากมีตัวเลือกน้อยลงในที่สุดจึงอาจทำให้คุณไม่พอใจที่อินเทอร์เฟซที่สมบูรณ์ยิ่งขึ้น
ตราบใดที่ภาระผูกพันของ CPU ดำเนินต่อไปนั่นก็เป็นวิธีที่ไม่สามารถระบุความหมายได้มากเกินไป สำหรับงานที่ผูกกับ CPU ภายใต้ CPython คุณต้องมีหลายกระบวนการแทนที่จะใช้หลายเธรดเพื่อให้มีโอกาสในการเพิ่มความเร็ว แต่ความเร็วที่คุณได้รับนั้นขึ้นอยู่กับรายละเอียดของฮาร์ดแวร์ระบบปฏิบัติการของคุณและโดยเฉพาะอย่างยิ่งกับการสื่อสารระหว่างกระบวนการที่คุณต้องการ ภายใต้หน้าปกกลเม็ดการปรับเทียบระหว่างกระบวนการทั้งหมดนั้นอาศัยหลักการพื้นฐานของระบบปฏิบัติการเดียวกันนั่นคือ API ระดับสูงที่คุณใช้เพื่อให้ได้มาซึ่งสิ่งเหล่านี้ไม่ใช่ปัจจัยหลักในความเร็วของบรรทัดล่าง
แก้ไข: ตัวอย่าง
นี่คือรหัสสุดท้ายที่แสดงในบทความที่คุณอ้างถึง แต่ฉันกำลังเพิ่มคำสั่งการนำเข้าที่จำเป็นเพื่อให้ใช้ได้:
from concurrent.futures import ProcessPoolExecutor
def pool_factorizer_map(nums, nprocs):
# Let the executor divide the work among processes by using 'map'.
with ProcessPoolExecutor(max_workers=nprocs) as executor:
return {num:factors for num, factors in
zip(nums,
executor.map(factorize_naive, nums))}
นี่คือสิ่งเดียวกันโดยใช้multiprocessing
แทน:
import multiprocessing as mp
def mp_factorizer_map(nums, nprocs):
with mp.Pool(nprocs) as pool:
return {num:factors for num, factors in
zip(nums,
pool.map(factorize_naive, nums))}
โปรดทราบว่ามีการเพิ่มความสามารถในการใช้multiprocessing.Pool
วัตถุเป็นตัวจัดการบริบทใน Python 3.3
อันไหนง่ายกว่าที่จะทำงานกับ? LOL ;-) พวกมันเหมือนกันหมด
หนึ่งความแตกต่างก็คือPool
การสนับสนุนรูปแบบต่างๆมากมายในการทำสิ่งที่คุณอาจไม่ตระหนักถึงวิธีการที่ง่ายก็สามารถจะจนกว่าคุณจะได้ปีนขึ้นไปค่อนข้างวิธีขึ้นโค้งการเรียนรู้
อีกครั้งวิธีที่ต่างกันทั้งหมดนั้นคือทั้งจุดแข็งและจุดอ่อน มันเป็นจุดแข็งเพราะความยืดหยุ่นอาจจำเป็นในบางสถานการณ์ พวกเขาเป็นจุดอ่อนเพราะ "ควรมีวิธีที่ชัดเจนเพียงวิธีเดียวเท่านั้น" โครงการที่ติดอยู่เฉพาะ (ถ้าเป็นไปได้) concurrent.futures
อาจจะง่ายต่อการดูแลรักษาในระยะยาวเนื่องจากการขาดความแปลกใหม่ที่ไม่มีเหตุผลในการใช้ API ขั้นต่ำของมัน