Python多线程抽象编程模型详解
概述
多线程编程是指在同一时间内,有多个线程在同时执行。Python中常用的多线程模块是threading
。
在多线程编程中,有两种常见的编程模型,即抢占式
和协作式
,Python采用的是协作式的多线程编程模型。
表示线程
在Python中,线程用threading.Thread
类表示,创建线程需要实现run
方法,此方法中包含线程要执行的代码。
import threading
import time
class MyThread(threading.Thread):
def __init__(self, num):
threading.Thread.__init__(self)
self.num = num
def run(self):
print("Thread {} started".format(self.num))
time.sleep(1)
print("Thread {} stopped".format(self.num))
thread1 = MyThread(1)
thread2 = MyThread(2)
thread1.start()
thread2.start()
创建线程
在Python中创建线程有三种方式,分别是:
- 使用
threading.Thread
类创建线程 - 使用
threading.Thread
子类化创建线程 - 使用
_thread
模块创建线程
使用threading.Thread
类创建线程
这是Python中最常见的创建线程的方式。
import threading
import time
def print_time(thread_name, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print("{}: {}".format(thread_name, time.ctime(time.time())))
thread1 = threading.Thread(target=print_time, args=("Thread 1", 2))
thread2 = threading.Thread(target=print_time, args=("Thread 2", 4))
thread1.start()
thread2.start()
使用threading.Thread
子类化创建线程
这种方式需要继承并重写threading.Thread
类。
import threading
import time
class MyThread(threading.Thread):
def __init__(self, thread_name, delay):
threading.Thread.__init__(self)
self.thread_name = thread_name
self.delay = delay
def run(self):
count = 0
while count < 5:
time.sleep(self.delay)
count += 1
print("{}: {}".format(self.thread_name, time.ctime(time.time())))
thread1 = MyThread("Thread 1", 2)
thread2 = MyThread("Thread 2", 4)
thread1.start()
thread2.start()
使用_thread
模块创建线程
这种方式与threading.Thread
类似,但是使用起来相对比较困难,需要直接使用_thread
模块的函数。
import _thread
import time
def print_time(thread_name, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print("{}: {}".format(thread_name, time.ctime(time.time())))
try:
_thread.start_new_thread(print_time, ("Thread 1", 2))
_thread.start_new_thread(print_time, ("Thread 2", 4))
except:
print("Error: 无法启动线程")
线程同步
在多线程编程中,为了避免线程之间的互相协调和访问共享资源发生冲突,需要采用线程同步技术。
常用的线程同步技术有:
- 互斥锁(
mutex
):一个线程用完临界资源后释放锁,其他等待访问此资源的线程进入临界区执行。 - 信号量(
semaphore
):同mutex
,不过有多个锁。临界区内最多只能同时运行有限数量的线程。 - 事件(
event
):一根线程A触发了一个事件a,另一个线程B可以等待这个事件的发生,并接收该事件发出的信息,从而达到两个线程之间的通信。
互斥锁
互斥锁使用threading.Lock
对象实现,可以确保线程互不干扰地访问共享资源。
import threading
import time
class Counter():
def __init__(self):
self.value = 0
self.lock = threading.Lock()
def increment(self):
self.lock.acquire()
try:
self.value += 1
finally:
self.lock.release()
def update_counter(counter):
for i in range(5):
time.sleep(0.5)
counter.increment()
print("Counter's total value is: {}".format(counter.value))
counter = Counter()
thread1 = threading.Thread(target=update_counter, args=(counter,))
thread2 = threading.Thread(target=update_counter, args=(counter,))
thread1.start()
thread2.start()
信号量
信号量使用threading.Semaphore
实现,可以设置允许访问的线程数量。
import threading
import time
class Test:
def __init__(self, sem):
self.sem = sem
def method(self):
self.sem.acquire()
print("当前线程:{}".format(threading.current_thread().name))
time.sleep(1)
self.sem.release()
sem = threading.Semaphore(3)
tests = [Test(sem) for i in range(10)]
threads = [threading.Thread(target=test.method) for test in tests]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
事件
事件使用threading.Event
实现。
import threading
import time
class EventTest:
def __init__(self, event):
self.event = event
def wait_for_event(self):
print("{} 开始等待事件".format(threading.current_thread().name))
self.event.wait()
print("{} 收到事件".format(threading.current_thread().name))
def send_event(self):
print("事件马上要处理")
time.sleep(2)
print("事件处理完毕")
self.event.set()
event = threading.Event()
tests = [EventTest(event) for i in range(2)]
threads = [threading.Thread(target=test.wait_for_event) for test in tests] + [threading.Thread(target=test.send_event) for test in tests]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
总结
本文详细介绍了Python多线程抽象编程模型。首先讲解了线程的表示,其次讲解了创建线程的三种方式,接着介绍了线程同步,包括互斥锁、信号量和事件。最后进行了总结,并给出了两个示例说明。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python多线程抽象编程模型详解 - Python技术站