python多进程
一、并发与并行
并行是指两个或者多个事件在同一时刻发生
并发是指两个或多个事件在同一时间段发生
并行指的是多个CPU,并发主要是针对一个CPU而已
并发的目的是充分利用处理器的每一个核,以达到最高的处理性能
二、Python多线程编程
多线程编程实例
thread_test.py
#1、实例化Thread
#2、继承Thread
from threading import Thread
import time
def sleep_task1():
print("sleep task1 2 seconds start!")
time.sleep(2)
print("sleep task1 2 seconds start!")
def sleep_task2():
print("sleep task2 3 seconds start!")
time.sleep(3)
print("sleep task2 3 seconds start!")
if __name__ == '__main__':
thread1 = Thread(target=sleep_task1)
thread1.start()
thread2 = Thread(target=sleep_task2)
thread2.start()
执行结果:线程交替执行
统计主线程时间
改写一下thread_test.py,统计线程执行时间,当开启一个程序的时候,会默认启动一个主线程,以下是统计主线程时间
#1、实例化Thread
#2、继承Thread
from threading import Thread
import time
def sleep_task(sleep_time):
print("sleep {} seconds start!".format(sleep_time))
time.sleep(sleep_time)
print("sleep task1 {} seconds start!".format(sleep_time))
if __name__ == '__main__':
start_time=time.time()
thread1 = Thread(target=sleep_task, args=(2, ))
thread1.start()
thread2 = Thread(target=sleep_task,args=(3,))
thread2.start()
end_time=time.time()
print("\nrun_time {}".format(end_time-start_time))
执行结果:
将子线程加入主线程
将新建的两个线程加入执行,程序使用join方法会等待子线程执行结束,从而统计到新建的两个子线程的执行时间
#1、实例化Thread
#2、继承Thread
from threading import Thread
import time
def sleep_task(sleep_time):
print("sleep {} seconds start!".format(sleep_time))
time.sleep(sleep_time)
print("sleep task1 {} seconds start!".format(sleep_time))
if __name__ == '__main__':
start_time=time.time()
thread1 = Thread(target=sleep_task, args=(2, ))
thread1.start()
thread2 = Thread(target=sleep_task,args=(3,))
thread2.start()
thread1.join()
thread2.join()
end_time=time.time()
print("\nrun_time {}".format(end_time-start_time))
执行结果:
使用daemon属性实现主子线程同时退出
但是主线程和子线程不是同时退出的,如果想让子线程和主线程同时退出可以使用Daemon属性,将子线程设置为守护线程
#1、实例化Thread
#2、继承Thread
from threading import Thread
import time
def sleep_task(sleep_time):
print("子线程执行")
print("sleep {} seconds start!".format(sleep_time))
time.sleep(sleep_time)
print("sleep task1 {} seconds start!".format(sleep_time))
print("子线程结束")
print("主线程执行")
if __name__ == '__main__':
start_time=time.time()
thread1 = Thread(target=sleep_task, args=(2, ))
thread1.daemon = True
thread1.start()
thread2 = Thread(target=sleep_task,args=(3,))
thread2.daemon = True
thread2.start()
end_time=time.time()
print("\nrun_time {}".format(end_time-start_time))
这样设置的子线程跟主线程同时退出,执行结果为:
继承Thread类方法实现Thread
thread_sleep.py
#1、实例化Thread
#2、继承Thread
from threading import Thread
import time
class SleepSpider(Thread):
def __init__(self, sleep_time):
self.sleep_time = sleep_time
super(SleepSpider, self).__init__()
def run(self):
print("子线程执行")
print("sleep {} seconds start!".format(self.sleep_time))
time.sleep(self.sleep_time)
print("sleep task1 {} seconds start!".format(self.sleep_time))
print("子线程结束")
print("主线程执行")
if __name__ == '__main__':
Thread1=SleepSpider(2)
Thread2=SleepSpider(3)
Thread1.start()
Thread2.start()
运行结果:
三、GIL
GIL的全称是Global Interpret Lock(全局解释器锁),来源是Python设计之初的考虑,为了数据安全所做的决定。每个CPU在同一之间只能执行一个线程(在单核CPU下的多线程其实都只是并发,并不是并行)。
某个线程想要执行,必须先拿到GIL,我们可以把GIL看做是“通行证”,并且在一个Python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行,GIL会释放的。