Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

API การทำงานแบบเธรดระดับต่ำใน Python (_thread)

โมดูล '_thread' ในไลบรารี Python 提供อินเทอร์เฟซระดับต่ำสำหรับการทำงานกับกระบวนการเบาๆ (light-weight processes) ที่มีหลายเธรดแบ่งปันพื้นที่ข้อมูลส่วนกลาง สำหรับการซิงโครไนซ์ โมดูลนี้กำหนดล็อคแบบง่าย (เรียกอีกอย่างว่า mutexes หรือ binary semaphores) โมดูล 'threading' ที่เป็นโมดูลสำเร็จรูป提供 API เธรดระดับสูงที่สร้างขึ้นบนโมดูลนี้

start_new_thread()

ฟังก์ชันระดับโมดูลนี้ใช้เพื่อเปิดเธรดใหม่ในกระบวนการปัจจุบัน ฟังก์ชันนี้รับอ็อบเจ็กต์ฟังก์ชันเป็นอาร์กิวเมนต์ ฟังก์ชันนี้จะถูกเรียกใช้เมื่อสร้างเธรดใหม่สำเร็จ ระยะเวลาของฟังก์ชันนี้สอดคล้องกับอายุของเธรด เธรดอาจถูกบล็อกโดยการเรียกฟังก์ชัน sleep()

โค้ดต่อไปนี้เป็นตัวอย่างง่ายของกลไกเธรดโดยใช้โมดูล _thread:

import _thread
import time

def run(threadName):
    count = 0
    for i in range(1, 6):
        time.sleep(5)
        print(threadName, i)

_thread.start_new_thread(run, ("child",))

for i in range(1, 6):
    print('main', i)
    time.sleep(5)

ฟังก์ชัน start_new_thread() สร้างเธรดใหม่ที่เรียกฟังก์ชัน run แบบขนาน มีลูปในฟังก์ชัน run() และในเธรดหลักของโปรแกรม การเรียกฟังก์ชัน sleep() ในทั้งสองทำให้เกิดการทำงานทับซ้อนกัน ดังนี้:

main 1
child 1
main 2
child 2
main 3
child 3
main 4
child 4
main 5
child 5

การซิงโครไนซ์ระหว่างเธรดทำได้โดยใช้อ็อบเจ็กต์ Lock ฟังก์ชัน allocate_lock() คืนค่าอ็อบเจ็กต์ล็อค มีเมธอดดังต่อไปนี้:

acquire()

เมธอดนี้ได้มาซึ่งล็อคโดยไม่มีเงื่อนไขจนกว่าจะถูกปล่อยโดยเธรดอื่น เธรดเดียวในเวลาเดียวกันเท่านั้นที่ได้มาซึ่งล็อค ค่าที่คืนคือ True หากได้มาซึ่งล็อคสำเร็จ False หากไม่สำเร็จ

release()

เมธอดนี้ปล่อยล็อค ล็อคต้องถูกได้มาซึ่งมาก่อนหน้านี้ แต่ไม่จำเป็นต้องเป็นโดยเธรดเดียวกัน

ในตัวอย่างต่อไปนี้ ประกาศเธรด 2 ตัว แต่ละตัวเรียกฟังก์ชัน run() พร้อมกัน ตัวหนึ่งได้มาซึ่งล็อคและเข้าสู่ฟังก์ชัน 'synchronized' ในขณะที่อีกตัวรอ:

import _thread
import time

def run(threadName):
    lock.acquire()
    synchronized(threadName)
    lock.release()

def synchronized(threadName):
    print(threadName, "has acquired lock")
    counter = 10
    while counter:
        time.sleep(1)
        print('*', end='')
        counter = counter - 1
    print('\n{} has released lock'.format(threadName))

lock = _thread.allocate_lock()
_thread.start_new_thread(run, ("t1",))
_thread.start_new_thread(run, ("t2",))

ผลลัพธ์

>>> 
t1 has acquired lock
**********
t1 has released lock
t2 has acquired lock
**********
t2 has released lock