什么是线程
线程是CPU执行的基本单元,线程的执行是无序的,同一进程下的线程之间资源共享,线程多用来存储I/O密集型任务
GIL:
全局解释器锁,因为CPython解释器,存在GIL全局解释器锁,保证同一时刻只有一个线程在执行,所以说相当于单核执行,线程并不能充分利用CPU资源
使用
- 使用模块 import threading
- threading.Thread()
—— target:线程要执行的目标函数
—— name:线程名称
—— args:传参数(元组)
—— kwargs:传参数(字典)
—— daemon:默认为False,主线程结束,不影响子线程执行
—— daemon:默认为True,主线程结束,子线程随之结束
线程
import threading
data = []
def run1(num,**kwargs):
global data
print(kwargs)
lock.acquire() # 加锁
for i in range(num):
#threading.currentThread().name:获取当前执行线程的名称
print(i,threading.currentThread().name)
# data.append(i)
sum += 1
lock.release() # 解锁
def run2(num):
global data
lock.acquire()
for i in range(num):
#threading.currentThread().name:获取当前执行线程的名称
print(i,threading.currentThread().name)
# data.append(i)
sum += 1
lock.release()
if __name__ == '__main__':
print('begin',threading.currentThread().name)
# 线程锁
lock = threading.Lock()
thread1 = threading.Thread(target=run1,name='线程1',args=(10000,),kwargs={'name':'李雷'},daemon=True)
thread2 = threading.Thread(target=run1,name='线程2',args=(10000,),daemon=True)
thread1.start()
thread2.start()
#join(),线程的阻塞(同步),让子线程中的任务执行完成,再回到主线程中执行
# thread1.join()
# thread2.join()
print(data,sum)
print('over', threading.currentThread().name)
线程池
在设计到多任务的情况下,往往需要大量的线程去执行任务,这是如果手动创建线程不方便,我们可以使用线程池
# 创建线程,执行任务,线程池中的线程任务调度不需要任务干预
from concurrent.futures import ThreadPoolExecutor
import requests
def download(url,filename,kwargs):
print(kwargs)
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
}
response = requests.get(url=url, headers=headers)
if response.status_code == 200:
return response.text,filename
def done(future):
# print(future.result())
text = future.result()[0]
filename = future.result()[1]
print(filename)
with open(filename,'w') as file:
file.write(text)
if __name__ == '__main__':
import threading
print('start',threading.currentThread().name)
task = []
for i in range(10):
url = 'https://www.baidu.com/?kw='+str(i)
task.append(url)
#创建线程池
pool = ThreadPoolExecutor(max_workers=10)
for index,url in enumerate(task):
print(index,url)
result = pool.submit(download,url,str(index)+'.html',kwargs={'name':'123'})
result.add_done_callback(done)
#shutdown:内部相当于每一个线程执行了join()方法
pool.shutdown(wait=True)
print('end', threading.currentThread().name)