📅  最后修改于: 2023-12-03 15:19:28.575000             🧑  作者: Mango
在并行计算中,多线程是一种广泛使用的技术。Python中的多线程模块是简单易用的,它提供了同步和非同步两种模式。
同步多线程意味着线程的执行是有顺序的,也就是说在一个线程执行完成之前,其他线程的执行都会被阻塞。Python中的 threading 模块提供了一些同步机制,如锁、条件变量、信号量等。
锁是最基本的同步机制之一。线程在访问共享资源之前会先请求获得锁,如果锁已经被其他线程获得了,那么当前线程会阻塞,直到锁被释放。
以下是一个简单的例子,其中两个线程并发地增加一个变量,使用锁可以保证操作的安全性。
import threading
def add_one(lock, count):
for i in range(100000):
lock.acquire()
count += 1
lock.release()
print("add_one finished")
def add_two(lock, count):
for i in range(100000):
lock.acquire()
count += 2
lock.release()
print("add_two finished")
def main():
count = 0
lock = threading.Lock()
thread1 = threading.Thread(target=add_one, args=(lock, count))
thread2 = threading.Thread(target=add_two, args=(lock, count))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(count)
if __name__ == '__main__':
main()
条件变量用于在线程之间共享状态信息,当一个线程需要等待某个条件满足时,它会阻塞并释放资源,直到另一个线程发出信号通知它条件已经满足。
以下是一个简单的例子,在线程1中当count的值达到1000时,唤醒线程2。
import threading
def wait_for_count(condition, count):
with condition:
condition.wait()
print("wait_for_count finished, count=", count)
def increase_count(condition, count):
for i in range(100):
count += 1
if count >= 1000:
with condition:
condition.notify_all()
print("increase_count count=", count)
print("increase_count finished, count=", count)
def main():
count = 0
condition = threading.Condition()
thread1 = threading.Thread(target=wait_for_count, args=(condition, count))
thread2 = threading.Thread(target=increase_count, args=(condition, count))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(count)
if __name__ == '__main__':
main()
非同步多线程不需要保证线程的执行顺序,它们可以并发执行。进程中每个非同步线程将有自己的控制流和存储器状态。Python提供了一些非同步机制,如Event对象和队列。
Event对象是一种简单的同步机制,它包括一个内部标志位和两种方法wait()和set()。当一个线程调用wait()方法时,如果标志位为False,该线程会被阻塞直到另一个线程调用set()方法把标志位设置为True。
以下是一个简单的例子,在线程2中等待线程1设置Event对象的标志位。
import threading
def wait_for_event(event):
print("wait_for_event start")
event.wait()
print("event is set")
def set_event(event):
print("set_event start")
event.set()
def main():
event = threading.Event()
thread1 = threading.Thread(target=set_event, args=(event,))
thread2 = threading.Thread(target=wait_for_event, args=(event,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
if __name__ == '__main__':
main()
队列可用于在线程之间传递信息和数据。Python提供了queue模块,它是线程安全的。
以下是一个简单的例子,其中一个线程将数字1-10放入队列中,另一个线程将它们取出并打印。
import queue
import threading
def producer(queue):
for i in range(1, 11):
queue.put(i)
def consumer(queue):
while not queue.empty():
print(queue.get())
def main():
queue = queue.Queue()
thread1 = threading.Thread(target=producer, args=(queue,))
thread2 = threading.Thread(target=consumer, args=(queue,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
if __name__ == '__main__':
main()
Python中的多线程模块提供了一些同步和非同步的多线程机制,在不同的场景下可以选择相应的方法。在使用多线程时,需要注意线程安全问题,避免出现数据竞争等问题,从而保证程序的正确性。