chzhiyi / -KnowledgeShare

6 stars 1 forks source link

20190417 - 多进程、多线程、协程(微线程) - baijing #54

Open KeepInLove1006 opened 5 years ago

KeepInLove1006 commented 5 years ago

多进程、多线程、协程(微线程)

进程:

想了解多进程是什么?我们首先要了解进程是什么?

进程就是正在运行的程序,比如我的电脑现在运行的QQ,一旦QQ运行了,系统就会给QQ分配了内存和资源。

单进程就是你的电脑只能做一件事,打开了QQ就没办法去做别的了。

但是你会发现电脑不只能运行QQ还可以打代码,这就是多进程。

一个单核的 CPU 在一个时间点上只能运行一个程序,之所以你的电脑能多个程序运行,是因为CPU在做着切换,因为切换的速度特别特别快,所有你感觉是同时运行。

线程:

线程在一个进程里面可以执行多个任务,在这里的每一个任务就是线程,线程可以说是程序用 CPU 的一个基本单元,所以一个程序里面如果只是单一的一个执行路径,那么它就是单线程的,一个程序如果有多个执行路径,那么它就是多线程的。

并行:在某一个时间段里,可以同时执行多个进程。

并发:就是在一个时间点,同时执行多个进程。

进程和进程之间是互相独立的,而一个进程里面的多个线程,这些线程之间是共享一个进程空间的。线程会抢占资源,所有就有了“互斥锁”,在 python 里,有一个叫做 GIL 锁,它就是用来控制线程执行权限的,所以当一个线程需要执行的时候,要先获得 GIL 之后才可以执行,这样就不会产生线程安全问题。

协程:

协程也叫做微线程,在一个线程里面可以执行多个函数,线程和进程是通过系统调度的,而微线程则不需要,可以根据需要自己调度,因为微线程是函数之间在切换,所以开销很小。


单进程:

# 常用的多线程的模块有这么几个
# _thread:之前有个 thread 模块被 python3 抛弃了改名为_thread但其实 _thread 也没什么人用
# threading
# Queue
import time

def moyu_time(name,delay,counter):
    while counter:
        time.sleep(delay)
        print("%s 开始摸鱼 %s" % (name,time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())))
        counter -= 1

if __name__ == '__main__':
    moyu_time('白鲸',1,20)

思考:摸鱼的例子

import threading
import time
from queue import Queue

class CustomThread(threading.Thread):
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.__queue = queue

    def run(self):
        while True:
            time.sleep(1)
            q_method = self.__queue.get()
            q_method()
            self.__queue.task_done()

def moyu():
    print(" 开始摸鱼 %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))

def queue_pool():
    queue = Queue(5)
    for i in range(queue.maxsize):
        t = CustomThread(queue)
        t.setDaemon(True)
        t.start()

    for i in range(20):
        queue.put(moyu)
    queue.join()

if __name__ == '__main__':
    queue_pool()