1. บทนำ
ความสำคัญของการประมวลผลแบบขนานใน Python
Python เป็นภาษาการเขียนโปรแกรมที่เรียบง่ายและใช้งานง่าย จึงถูกนำไปใช้ในหลากหลายด้าน อย่างไรก็ตาม เมื่อมีการประมวลผลข้อมูลหรือการคำนวณที่ซับซ้อน ความเร็วของ Python อาจกลายเป็นข้อจำกัด เพื่อแก้ไขปัญหานี้ การใช้ “การประมวลผลแบบขนาน” ซึ่งสามารถทำงานหลายงานพร้อมกันได้ จึงมีบทบาทสำคัญ บทความนี้จะอธิบายวิธีการนำการประมวลผลแบบขนานมาใช้ใน Python ตั้งแต่แนวทางพื้นฐานไปจนถึงตัวอย่างการใช้งานจริง
2. วิธีการประมวลผลแบบขนานใน Python
วิธีหลักของการประมวลผลแบบขนาน
Python มีหลายวิธีในการทำงานแบบขนาน โดยหลัก ๆ มี 3 วิธีดังนี้:
- มัลติเธรด (
threading
โมดูล)
ใช้หลายเธรดเพื่อทำงานพร้อมกัน แต่ด้วยข้อจำกัดของ GIL (Global Interpreter Lock) ใน Python ทำให้ประสิทธิภาพถูกจำกัดในงานที่ใช้ CPU หนัก - มัลติโปรเซส (
multiprocessing
โมดูล)
แต่ละโปรเซสมีหน่วยความจำแยกกัน ทำให้ไม่ถูกจำกัดด้วย GIL และสามารถใช้ CPU หลายคอร์ได้เต็มที่ เหมาะกับการประมวลผลข้อมูลขนาดใหญ่และงานคำนวณหนัก - การประมวลผลแบบอะซิงโครนัส (
asyncio
โมดูล)
เหมาะสำหรับงานที่เป็น I/O-bound (เช่น การสื่อสารเครือข่ายหรือการอ่าน/เขียนไฟล์) ช่วยให้สามารถจัดการเวลารอคอยได้อย่างมีประสิทธิภาพ

3. มัลติโปรเซส vs มัลติเธรด
ผลกระทบของ GIL (Global Interpreter Lock)
Python มีระบบที่เรียกว่า GIL ทำให้ในเวลาเดียวกันมีเพียงเธรดเดียวที่ทำงานได้ สิ่งนี้เป็นสาเหตุที่การประมวลผลแบบเธรดไม่สามารถเพิ่มประสิทธิภาพในงานที่ใช้ CPU มากได้ จึงเหมาะกับงาน I/O-bound ที่มีเวลารอคอยมากกว่า
ข้อดีและข้อจำกัดของมัลติเธรด
เธรดมีความเบา และเหมาะสำหรับงาน I/O เช่น การอ่านไฟล์หรือการเชื่อมต่อเครือข่าย แต่ไม่เหมาะสำหรับงานที่ใช้ CPU หนัก เนื่องจาก GIL ทำให้ไม่สามารถใช้ CPU หลายคอร์ได้เต็มที่
“`python
import threading
import time
def worker(num):
print(f”Worker {num} starting”)
time.sleep(2)
print(f”Worker {num} finished”)
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()
“`
โค้ดนี้แสดงการทำงานของ 5 เธรดพร้อมกัน โดยแต่ละเธรดจะหน่วงเวลา 2 วินาทีแล้วจบการทำงาน การใช้มัลติเธรดช่วยให้เห็นการทำงานพร้อมกันได้ชัดเจน
ข้อดีของมัลติโปรเซส
มัลติโปรเซสสามารถหลีกเลี่ยงข้อจำกัดของ GIL ได้ แต่ละโปรเซสทำงานในหน่วยความจำแยกกัน ทำให้สามารถใช้ CPU หลายคอร์ได้เต็มประสิทธิภาพ โดยเฉพาะอย่างยิ่งในงานที่คำนวณหนักหรือต้องจัดการข้อมูลขนาดใหญ่
“`python
from multiprocessing import Process
import time
def worker(num):
print(f”Worker {num} starting”)
time.sleep(2)
print(f”Worker {num} finished”)
if __name__ == ‘__main__’:
processes = []
for i in range(5):
p = Process(target=worker, args=(i,))
processes.append(p)
p.start()
for p in processes:
p.join()
“`
ตัวอย่างนี้แสดงการทำงานของ 5 โปรเซสพร้อมกัน แต่ละโปรเซสทำงานแยกจากกัน และ `join()` จะรอให้ทุกโปรเซสทำงานเสร็จสิ้นก่อนโปรแกรมจะไปต่อ
4. วิธีการนำการประมวลผลแบบขนานไปใช้ใน Python
การใช้โมดูล multiprocessing
โมดูล multiprocessing
สามารถจัดการหลายโปรเซสได้อย่างมีประสิทธิภาพ ตัวอย่างโค้ดด้านล่างเป็นการใช้ process pool ในการคำนวณ
“`python
from multiprocessing import Pool
def square(x):
return x * x
if __name__ == ‘__main__’:
with Pool(4) as p:
result = p.map(square, [1, 2, 3, 4, 5])
print(result)
“`
โค้ดนี้ใช้ 4 โปรเซสในการคำนวณกำลังสองของตัวเลขในลิสต์ ผลลัพธ์ที่ได้จะเป็นลิสต์ที่มีค่าคำนวณเสร็จ
5. การประมวลผลแบบอะซิงโครนัสและการใช้งาน
การใช้ asyncio
asyncio
เหมาะสำหรับงานที่มีการรอ I/O เช่น การสื่อสารเครือข่ายหรือไฟล์ I/O โดยระหว่างรอสามารถทำงานอื่น ๆ ไปพร้อมกันได้
“`python
import asyncio
async def worker(num):
print(f’Worker {num} starting’)
await asyncio.sleep(1)
print(f’Worker {num} finished’)
async def main():
tasks = [worker(i) for i in range(5)]
await asyncio.gather(*tasks)
asyncio.run(main())
“`
โค้ดนี้รัน 5 งานแบบอะซิงโครนัสพร้อมกัน ใช้ `await` เพื่อรอในแต่ละงานโดยไม่บล็อกงานอื่น

6. การปรับจูนประสิทธิภาพของการประมวลผลแบบขนาน
การใช้ Joblib
Joblib
เป็นไลบรารีที่ช่วยให้การประมวลผลข้อมูลหรือการฝึกโมเดล Machine Learning มีประสิทธิภาพมากขึ้น ตัวอย่างเช่น:
“`python
from joblib import Parallel, delayed
def heavy_task(n):
return n ** 2
results = Parallel(n_jobs=4)(delayed(heavy_task)(i) for i in range(10))
print(results)
“`
โดยกำหนด n_jobs
เพื่อควบคุมจำนวนโปรเซสที่ทำงานพร้อมกัน
7. การประยุกต์ใช้งานจริงของการประมวลผลแบบขนานใน Python
การประมวลผลข้อมูลและการ Web Scraping
การใช้การประมวลผลแบบขนานใน Python มีประโยชน์อย่างมาก เช่น ในการดึงข้อมูลจากหลายเว็บไซต์พร้อมกัน (web scraping) หรือการประมวลผลข้อมูลจำนวนมาก รวมถึงการฝึกโมเดล Machine Learning ด้วย multiprocessing
หรือ Joblib
8. สรุป
การประมวลผลแบบขนานเป็นเทคนิคสำคัญที่จะช่วยให้ Python ทำงานได้เต็มประสิทธิภาพ การใช้ threading
, multiprocessing
, asyncio
, และ Joblib
อย่างเหมาะสม จะช่วยเพิ่มประสิทธิภาพในงานหลากหลายประเภทได้อย่างมาก