06多核、多进程、多线程

实现并行计算有三种方式,多线程,多进程,多进程+多线程。

多内核(multicore chips)是指在一枚处理器(chip)中集成两个或多个完整的计算引擎(内核),
计算机的cpu物理核数是同时可以并行的线程数量(cpu只能看到线程,线程是cpu调度分配的最小单位),
一个核只能运行一个线程。
进程是操作系统资源分配(内存,显卡,磁盘)的最小单位,
线程是执行调度(即cpu调度)的最小单位(cpu看到的都是线程而不是进程),
一个进程可以有一个或多个线程,线程之间共享进程的资源,
通过这样的范式,就可以减少进程的创建和销毁带来的代价,可以让进程少一点,保持相对稳定,不断去调度线程就好。


多线程指的是,在一个进程中开启多个线程,
简单的讲:如果多个任务共用一块地址空间,那么必须在一个进程内开启多个线程。详细的讲分为4点:
1. 多线程共享一个进程的地址空间(数据),一个进程内的多个线程的pid一样
2. 线程比进程更轻量级,线程比进程更容易创建可撤销,在许多操作系统中,创建一个线程比创建
一个进程要快10-100倍,在有大量线程需要动态和快速修改时,这一特性很有用
3. 若多个线程都是cpu密集型的,那么并不能获得性能上的增强,但是如果存在大量I/O处理,
拥有多个线程允许这些活动彼此重叠运行,从而会加快程序执行的速度。
4. 在多cpu系统中,为了最大限度的利用多核,可以开启多个线程,比开进程开销要小的多。
(这一条并不适用于python)


1.单核多线程,并发,不是并行
1.多核多线程,线程数<核数,并行
1.多核多线程,线程数>核数,并发,(其中有些线程就会不断切换,并发执行,但实际上最大的并行数量还是当前这个进程中的核的数量,
所以盲目增加线程数不仅不会让你的程序更快,反而会给你的程序增加额外的开销。)

关于效率:
任务可以分为计算密集型和IO密集型:
io密集型:有阻塞的状态,就是一直会执行CPU(中间就一个等待状态,这个就叫做IO密集型)。例如:sleep状态
计算密集型任务:没有等待的状态就是计算密集型,从上到下执行没有等待。

在Python中没法同时使用多个CPU,在同一时刻,多个线程是互相抢占资源的,在cpython运行中加了一把锁(GIL)。

如果任务是IO密集型的可以使用多线程(阻塞等待时,就是放GIL,给另一个线程执行的机会,并发)
如果是计算密集型任务时,无法使用多线程(如果遇到CPU密集型的线程,一只占用CPU,不会被I/O阻塞)

计算密集型:多进程效率高,如金融分析
IO密集型:多线程效率高,如socket,爬虫,web

性能测试
# 计算密集型
from multiprocessing import Process
from threading import Thread
import time, os

def task():
    res = 1
    for i in range(100000000):
        res *= i

if __name__ == '__main__':
    start_time = time.time()
    print(os.cpu_count()) #本机为4核
    l = []
    for i in range(4):
        # p = Process(target=task)   #spend_time: 16.10278034210205,计算密集型,多进程效率高
        p = Thread(target=task)      #spend_time: 26.059650897979736
        l.append(p)
        p.start()

    for p in l:
        p.join()

    end_time = time.time()
    print('spend_time:',end_time-start_time)

 

 

# I/O密集型
from multiprocessing import Process
from threading import Thread
import time, os

def task():
    time.sleep(2)
    print('------->')

if __name__ == '__main__':
    start_time = time.time()
    print(os.cpu_count()) #本机为4核
    l = []
    for i in range(400):
        # p = Process(target=task)   #spend_time: 30.915207862854004
        p = Thread(target=task)      #spend_time: 2.059750556945801,I/O密集型,多线程效率高
        l.append(p)
        p.start()

    for p in l:
        p.join()

    end_time = time.time()
    print('spend_time:',end_time-start_time)

 

 





posted @ 2021-03-01 18:33  cheng4632  阅读(966)  评论(0编辑  收藏  举报