1)python中的GIL:
GIL: global interpreter lock (全局解释器锁)
cpython中一个线程对应c语言中的一个线程,GIL使得同一时刻只有一个线程在一个cpu上执行字节码,无法映射多个线程到多个cpu上,不能发挥多核优势。
GIL会根据执行的字节码行数以及时间片段释放GIL,GIL遇到io操作的时候会主动释放。
2)多线程编程 threading
线程是操作系统调度的最小单元import time
import threading
def get_html_detail(url):
print('开始获取html界面')
time.sleep(3)
print('获取html界面元素成功')
def get_url(url):
print('获取界面元素url开始')
time.sleep(3)
print('获取界面元素url结束')
thread1 = threading.Thread(target=get_html_detail,args=('url',))
thread2 = threading.Thread(target=get_url,args=('url',))
start_time = time.time()
#设置线程为守护线程,主线程结束时推出
#thread1.setDaemon(True)
#thread2.setDaemon(True)
thread1.start()
thread2.start()
#将两个线程加入主线程
thread1.join()
thread2.join()
#主线程退出,子线程自动kill
print('持续时间 {}'.format(time.time() - start_time))
------------------------------------------------
debug下可以看到有三个线程存在:MainThread thread-6 thread-7
线程是并行的thread-1 thread-2 开始后不会影响到MainThread的运行所以“print(‘持续时间 {}’.format(time.time() - start_time))”这个代码也会运行。
setDaemon将线程设置为守护线程,主线程退出时自动退出
join将子线程加入主线程,当子线程结束后才运行主线程代码。
通过继承thread实现多线程
import time
import threading
class GETHTML(threading.Thread):
def __init__(self,name):
super().__init__(name=name)
def run(self):
print('开始获取html界面')
time.sleep(3)
print('获取html界面元素成功')
class GETURL(threading.Thread):
def __init__(self,name):
super().__init__(name=name)
def run(self):
print('获取界面元素url开始')
time.sleep(4)
print('获取界面元素url结束')
if __name__ == '__main__':
thread1 = GETHTML('get_html')
thread2 = GETHTML('get_url')
start_time = time.time()
print('主线程开始')
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print('主线程用时{}'.format(time.time() - start_time))
----------------------------------------
主线程开始
开始获取html界面
开始获取html界面
获取html界面元素成功
获取html界面元素成功
主线程用时3.017345666885376