Python多线程与多进程

Python多线程与多进程

目录

多线程,多进程介绍
计算密集型
I/O密集型

多线程,多进程介绍

本篇仅展示代码,详细多线程教学移步(python爬虫之多线程)

多线程以及线程池:

from concurrent.futures import ThreadPoolExecutor

def work():
    res = 0
    for i in range(100000000):
        res += i


def main_thread():
    # 多线程
    # 让线程池创建100个线程
    with ThreadPoolExecutor(100) as t: 
        # 在启用的线程中执行100次work()方法
        [t.submit(work) for i in range(100)]
    print('多线程', end='')

多进程:
多进程不用池是因为在创建进程池时会限制进程创建数量,这里为了演示会超过限制报错因此直接没用,如果你想用的话直接把线程的ThreadPoolExecutor换成ProcessPoolExecutor就行了非常简单

import multiprocessing

def work():
    res = 0
    for i in range(100000000):
        res += i

def main_process():
    # 多进程
    # 创建100个进程对象,每个对象执行work()方法
    M = [multiprocessing.Process(target=work) for i in range(100)]
    for m in M:
        m.start()
    for m in M:
        m.join()
    print('多进程', end='')

计算密集型

由于GIL锁的存在,在CPython中只能有一个线程执行任务,假如一个计算密集型的任务需要 10s 的执行时间,总共有4个这样的任务

多进程: 需要开启 4 个进程,但是 4 个 CPU 并行,最终只需要消耗 10s 多一点的时间。

多线程: 只需要开1 个进程,这个进程开启 4 个线程,开启线程所消耗的资源很少,但是由于最终执行是只有一个 CPU 可以工作,所以最终消耗 40s 多的时间。

废话不多说直接上代码

import multiprocessing
import time
from concurrent.futures import ThreadPoolExecutor


def work():
    res = 0
    for i in range(100000000):
        res += i

def main_thread():
    # 多线程
    with ThreadPoolExecutor(10000) as t:
        [t.submit(work) for i in range(10000)]
    print('多线程', end='')

def main_process():
    # 多进程
    M = [multiprocessing.Process(target=work) for i in range(100)]
    for m in M:
        m.start()
    for m in M:
        m.join()
    print('多进程', end='')


def main(work_task):
    s_time = time.time()
    work_task()
    e_time = time.time()
    print(f'用时{e_time - s_time}秒')


if __name__ == '__main__':
    main(main_process)
	main(main_thread)

结果:

image-20240121191914596

image-20240121191416576

I/O密集型

假如是多个 IO密集型 的任务 (例如input(),time.sleep())CPU 大多数时间是处于闲置状态,频繁的切换

多进程: 进程进行切换需要消耗大量资源

多线程: 线程进行切换并不需要消耗大量资源,即使有GIL锁的存在,最终也会以量取胜多进程

在刚刚的计算密集型测试中,笔者吃了个饭才跑完多线程的测试,这次给线程老弟也上上强度,直接sleep一万次

import multiprocessing
import time
from concurrent.futures import ThreadPoolExecutor


def work():
    time.sleep(1)


def main_thread():
    # 多线程
    with ThreadPoolExecutor(10000) as t:
        [t.submit(work) for i in range(10000)]
    print('多线程', end='')


def main_process():
    # 多进程
    M = [multiprocessing.Process(target=work) for i in range(10000)]
    for m in M:
        m.start()
    for m in M:
        m.join()
    print('多进程', end='')


def main(work_task):
    s_time = time.time()
    work_task()
    e_time = time.time()
    print(f'用时{e_time - s_time}秒')


if __name__ == '__main__':
    main(main_process)
    main(main_thread)

image-20240121192526430
image-20240121192542795

你可能感兴趣的:(Study,python,java,数据库)