03月20, 2019

【进阶】多线程

左手画圆,右手画方

各位谁能左手画圆的同时右手画方?简单来讲就是同时做两件事,一心二用。而python多线程就是干这件事的,不只是python,很多编程语言都有多线程这个功能。我们一步一步来,先一心一用。

一心一用

import time
import threading
# 左手画圆
def draw_circle(cost):
    print("start draw a circle ", time.ctime())
    time.sleep(cost)
    print("draw a circle ", time.ctime())
# 右手画方
def draw_square(cost):
    print("start draw a squre", time.ctime())
    time.sleep(cost)
    print("draw a squre ", time.ctime())

def single_thread():
    draw_circle(1)
    draw_square(2)

if __name__ == '__main__':
    print("start single_thread ", time.ctime())
    single_thread()
    print("end single_thread ", time.ctime())

运行结果:

start single_thread  Sun Jan 21 10:14:23 2018
start draw a circle  Sun Jan 21 10:14:23 2018
draw a circle  Sun Jan 21 10:14:24 2018
start draw a squre Sun Jan 21 10:14:24 2018
draw a squre  Sun Jan 21 10:14:26 2018
end single_thread  Sun Jan 21 10:14:26 2018

title 我们可以看到先画了圆花费1秒钟,后画了方花费2秒钟,总计花费3秒钟

一心二用

引用了python的线程库:threading

import time
import threading
# 左手画圆
def draw_circle(cost):
    print("start draw a circle ", time.ctime())
    time.sleep(cost)
    print("draw a circle ", time.ctime())
# 右手画方
def draw_square(cost):
    print("start draw a squre", time.ctime())
    time.sleep(cost)
    print("draw a squre ", time.ctime())

def multi_thread():
    draw_circle_thread = threading.Thread(target=draw_circle, args=(1,))
    draw_square_thread = threading.Thread(target=draw_square, args=(2,))
    draw_circle_thread.start()
    draw_square_thread.start()

if __name__ == '__main__':
    print("start ", time.ctime())
    multi_thread()
    print("end ", time.ctime())

运行结果:

start  Sun Jan 21 10:20:14 2018
start draw a circle  Sun Jan 21 10:20:14 2018
start draw a squre Sun Jan 21 10:20:14 2018
end  Sun Jan 21 10:20:14 2018
draw a circle  Sun Jan 21 10:20:15 2018
draw a squre  Sun Jan 21 10:20:16 2018

title 看上去是在10:20:14同时开始画圆和画方,分别花费1秒和两秒。但是你们有没有发现一个很诡异的地方,为什么在画之前就end了。这是因为没有设置等待这两个子线程执行完再往下走。 我们只需要补充两个设置语句join:

import time
import threading
# 左手画圆
def draw_circle(cost):
    print("start draw a circle ", time.ctime())
    time.sleep(cost)
    print("draw a circle ", time.ctime())
# 右手画方
def draw_square(cost):
    print("start draw a squre", time.ctime())
    time.sleep(cost)
    print("draw a squre ", time.ctime())

def multi_thread():
    draw_circle_thread = threading.Thread(target=draw_circle, args=(1,))
    draw_square_thread = threading.Thread(target=draw_square, args=(2,))
    draw_circle_thread.start()
    draw_square_thread.start()
    draw_circle_thread.join()  // 调用 join 之后主线程会等待子线程运行完毕之后才会往下走
    draw_square_thread.join()  //

if __name__ == '__main__':
    print("start ", time.ctime())
    multi_thread()
    print("end ", time.ctime())

运行结果:

start  Sun Jan 21 10:23:02 2018
start draw a circle  Sun Jan 21 10:23:02 2018
start draw a squre Sun Jan 21 10:23:02 2018
draw a circle  Sun Jan 21 10:23:03 2018
draw a squre  Sun Jan 21 10:23:04 2018
end  Sun Jan 21 10:23:04 2018

title 现在看来就正常了,并且我们可以看到总计只用了2秒,因为是同时开始执行的,比单线程快了1秒钟,这就是多线程存在的意义和价值。

##但是 python多线程其实是假的多线程,具体为什么呢?大家可以去搜一下,简单来讲就是GIL的锅,详细内容资料很多不再赘述,感兴趣的同学可以去看看。

本文链接:http://www.yuqiaochuang.com/post/左手画圆,右手画方.html

-- EOF --

Comments

""