Python 和多线程。这是个好主意吗?
不,这不是个好主意。由于存在所谓的全局解释器锁,Python 中无法实现多线程。多线程程序包含两个或多个可以并发运行的部分,每个部分可以同时处理不同的任务,从而充分利用可用资源,特别是当您的计算机有多个 CPU 时。多线程使您能够以多种活动可以同时在同一个程序中执行的方式编写代码。
Python 不允许多线程,但如果您想以需要等待 IO 之类的速度运行程序,那么它会被大量使用。而线程包不能让您使用额外的 CPU 核心。Python 不支持多线程,因为 Cpython 解释器上的 Python 不支持通过多线程实现真正的多核执行。但是,Python 确实有一个线程库。
GIL 不会阻止线程。 GIL 所做的只是确保一次只有一个线程在执行 Python 代码;控制权仍在线程之间切换。但是,如果混合使用 C 扩展和 I/O(例如 PIL 或 numpy 操作),任何 C 代码都可以与一个活动的 Python 线程并行运行。
threading 模块
我们仍然可以使用 threading 模块执行多线程。进程中的多个线程与主线程共享相同的数据空间,因此可以比单独的进程更轻松地共享信息或相互通信。
Python 2.4 中包含的较新的线程模块比上一节讨论的线程模块提供了更强大、更高级的线程支持。
threading 模块公开了 thread 模块的所有方法,并提供了一些附加方法 -
threading.activeCount() - 返回处于活动状态的线程对象的数量。
threading.currentThread() - 返回调用方线程控制中的线程对象的数量。
threading.enumerate() - 返回当前处于活动状态的所有线程对象的列表。
threading 模块具有 Thread 类,实现线程。 Thread 类提供的方法如下 -
run() - run() 方法是线程的入口点。
start() - start() 方法通过调用 run 方法启动线程。
join([time]) - join() 等待线程终止。
isAlive() - isAlive() 方法检查线程是否仍在执行。
getName() - getName() 方法返回线程的名称。
setName() - setName() 方法设置线程的名称。
示例
附带的 threading 模块Python 包含一个易于实现的锁定机制,允许您同步线程。通过调用 Lock() 方法来创建新的锁,该方法返回新锁。
新锁对象的 acquire(blocking) 方法用于强制线程同步运行。可选的阻止参数使您能够控制线程是否等待获取锁。
如果 blocking 设置为 0,则如果无法获取锁,则线程立即返回 0 值,如果已获取锁,则返回 1。如果将阻止设置为 1,则线程阻塞并等待释放锁。
新锁对象的 release() 方法用于在不再需要锁时释放锁。
import threading import time class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print ("Starting " + self.name) # Get lock to synchronize threads threadLock.acquire() print_time(self.name, self.counter, 3) # Free lock to release next thread threadLock.release() def print_time(threadName, delay, counter): while counter: time.sleep(delay) print ("%s: %s" % (threadName, time.ctime(time.time()))) counter -= 1 threadLock = threading.Lock() threads = [] # Create new threads thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Start new Threads thread1.start() thread2.start() # Add threads to thread list threads.append(thread1) threads.append(thread2) # Wait for all threads to complete for t in threads: t.join() print ("Exiting Main Thread")
输出
Starting Thread-1 Starting Thread-2 Thread-1: Fri Aug 12 05:49:52 2022 Thread-1: Fri Aug 12 05:49:53 2022 Thread-1: Fri Aug 12 05:49:54 2022 Thread-2: Fri Aug 12 05:49:56 2022 Thread-2: Fri Aug 12 05:49:58 2022 Thread-2: Fri Aug 12 05:50:00 2022 Exiting Main Thread