掌握 Python 中多线程和多进程的使用方法

文章目录

  • 1. Python 多进程
  • 1.1 常见用法
  • 1. 创建进程
  • 2. 进程池
  • 3. 进程间通信
  • 4. 进程同步
  • 1.2 结合进度条显示
  • 2. Python 多线程
  • 2.1 常见用法
  • 1. 使用线程池
  • 2.2 结合进度条显示

  • 1. Python 多进程

    1.1 常见用法

    multiprocessing 是 Python 标准库中的一个模块,用于在多核或多处理器环境中并行执行任务。它提供了一种便捷的方法来创建和管理多个进程,以实现并行计算。multiprocessing 模块的功能包括创建进程、进程间通信、进程同步、进程池、共享数据结构等。

    下面是一些 multiprocessing 模块的常用功能和用法介绍:

    1. 创建进程

    你可以使用 multiprocessing.Process 类创建新的进程。目标函数可以接受参数并在进程中执行。

    import multiprocessing
    
    def worker_function(name):
        print(f"Hello from process {name}")
    
    if __name__ == '__main__':
        # 创建进程
        process1 = multiprocessing.Process(target=worker_function, args=("Process 1",))
        process2 = multiprocessing.Process(target=worker_function, args=("Process 2",))
    
        # 启动进程
        process1.start()
        process2.start()
    
        # 等待进程完成
        process1.join()
        process2.join()
    

    2. 进程池

    multiprocessing.Pool 类提供了一种方式,可以在进程池中并行执行任务。

    import multiprocessing
    
    def square(x):
        return x * x
    
    if __name__ == '__main__':
        # 创建进程池
        with multiprocessing.Pool(processes=4) as pool:
            # 并行执行任务
            results = pool.map(square, range(10))
            print(results)
    

    3. 进程间通信

    multiprocessing 提供了管道 (Pipe) 和队列 (Queue) 来实现进程间的通信。

    示例代码:

    import multiprocessing
    
    def producer(pipe):
        # 通过管道发送数据
        pipe.send("Hello from producer")
    
    def consumer(pipe):
        # 从管道接收数据
        message = pipe.recv()
        print(message)
    
    if __name__ == '__main__':
        # 创建管道
        parent_pipe, child_pipe = multiprocessing.Pipe()
        
        # 创建进程
        p1 = multiprocessing.Process(target=producer, args=(child_pipe,))
        p2 = multiprocessing.Process(target=consumer, args=(parent_pipe,))
        
        # 启动进程
        p1.start()
        p2.start()
        
        # 等待进程完成
        p1.join()
        p2.join()
    

    4. 进程同步

    multiprocessing 提供了锁 (Lock)、条件变量 (Condition) 和信号量 (Semaphore) 等同步原语,以便在进程间进行同步。

    示例代码:

    import multiprocessing
    
    def worker(lock, num):
        with lock:
            # 锁定后执行的操作
            print(f"Locked by process {num}")
    
    if __name__ == '__main__':
        # 创建锁
        lock = multiprocessing.Lock()
    
        # 创建进程
        processes = []
        for i in range(3):
            process = multiprocessing.Process(target=worker, args=(lock, i))
            processes.append(process)
    
        # 启动进程
        for process in processes:
            process.start()
    
        # 等待所有进程完成
        for process in processes:
            process.join()
    

    1.2 结合进度条显示

    (1)列表作为参数

    def square(x):
        return x * x
    
    import multiprocessing
    from tqdm import tqdm
    
    iters = [1, 2, 3, 4]
    pool = multiprocessing.Pool(processes = 5)
    ret_list = [ret for ret in tqdm(pool.imap(func=square, iterable=iters), total=len(iters))]
    pool.close()
    pool.join()
    

    (2)字典,需要转换成列表

    def square(args):
    	x, y = args
        return x * y
    
    import multiprocessing
    from tqdm import tqdm
    
    dict_map = {"1": 1, "2": 2, "3": 3}
    iters = [(k, v) for k, v in dict_map.items()]
    pool = multiprocessing.Pool(processes = 5)
    ret_list = [ret for ret in tqdm(pool.imap(func=square, iterable=iters), total=len(iters))]
    pool.close()
    pool.join()
    

    2. Python 多线程

    在 Python 中,多线程是一种并行执行多个任务的方法。threading 模块提供了多线程编程的支持。通过使用多线程,你可以并行执行多个任务,从而提高程序的效率,尤其是在 I/O 密集型任务中(例如网络请求、文件读写等)。多线程适合于 I/O 密集型任务,因为 Python 的全局解释器锁(GIL)会限制 CPU 密集型任务的并行执行。

    2.1 常见用法

    在 Python 中,threading 模块提供了多线程编程的基础。你可以通过创建 threading.Thread 对象来创建新的线程,并将目标函数和参数传递给线程。在创建和启动线程后,可以通过 join() 方法等待线程完成执行。

    下面是一个示例,展示了多线程的基本用法:

    import threading
    import time
    
    # 定义目标函数
    def worker_function(name, sleep_time):
        print(f"Thread {name} starting")
        time.sleep(sleep_time)
        print(f"Thread {name} finishing")
    
    if __name__ == '__main__':
        # 创建线程
        thread1 = threading.Thread(target=worker_function, args=("Thread 1", 2))
        thread2 = threading.Thread(target=worker_function, args=("Thread 2", 3))
    
        # 启动线程
        thread1.start()
        thread2.start()
    
        # 等待线程完成
        thread1.join()
        thread2.join()
    
        print("All threads finished.")
    

    在这个示例中,我们定义了一个目标函数 worker_function,该函数接收线程的名字和睡眠时间作为参数。在 __name__ == '__main__' 中,我们创建两个线程,并将目标函数和参数传递给线程。启动线程后,我们使用 join() 方法等待线程完成。

    1. 使用线程池

    除了直接创建线程外,你还可以使用 concurrent.futures 模块中的 ThreadPoolExecutor 来创建线程池,并执行任务。线程池可以方便地管理多个线程,并发执行多个任务。

    示例代码:

    from concurrent.futures import ThreadPoolExecutor
    import time
    
    # 定义目标函数
    def worker_function(name, sleep_time):
        print(f"Thread {name} starting")
        time.sleep(sleep_time)
        print(f"Thread {name} finishing")
        return f"{name} completed"
    
    if __name__ == '__main__':
        # 创建线程池
        with ThreadPoolExecutor(max_workers=2) as executor:
            # 提交任务到线程池
            future1 = executor.submit(worker_function, "Thread 1", 2)
            future2 = executor.submit(worker_function, "Thread 2", 3)
    
            # 获取结果
            result1 = future1.result()
            result2 = future2.result()
    
            print(result1)
            print(result2)
    

    在这个示例中,我们使用 ThreadPoolExecutor 创建一个线程池,并设定最大工作线程数。通过 executor.submit() 方法提交任务到线程池中。然后通过调用 future.result() 来获取任务的结果。

    需要注意的是,由于 Python 的全局解释器锁(GIL),多线程在 CPU 密集型任务中的性能受限。因此,多线程更适合 I/O 密集型任务。如果你的任务是 CPU 密集型任务,可以考虑使用 multiprocessing 模块来利用多核 CPU。

    2.2 结合进度条显示

    def square(x):
        return x * x
    
    arg_list = [1, 2, 3, 4]
    with ThreadPoolExecutor(max_workers=20) as executor:
    	ret_list = list(tqdm(executor.map(square, arg_list), total=len(arg_list)))
    

    作者:SmallerFL

    物联沃分享整理
    物联沃-IOTWORD物联网 » 掌握 Python 中多线程和多进程的使用方法

    发表回复