定义1、进程:就是一组资源的集合。一个程序就是一个进程。
- 线程是用来干活的,只有进程的话是没办法运行的,进程里其实是线程在具体干活的。
- 线程和线程之间是互相独立的。
import threading #引入线程模块
import time
def run():
time.sleep(5)
print('over')
start_time=time.time()
run()
run()
run()
run()
end_time=time.time()
print('run_time', end_time-start_time)
#结果:run_time=20.38954234234
上面这个例子是单线程执行的,运行时间是20多秒,如果使用多线程,则会并行执行,执行结果应该是5秒左右。
import threading
import time
def run():
time.sleep(5)
print('over')
start_time=time.time()
thread_list = []
for i in range(5):
t=threading.Thread(target=run) #实例化一个线程
t.start() #启动这个线程
thread_list.append(t)
for thread in thread_list:
thread.join() #主线程等待子线程
end_time=time.time()
print('run_time=', end_time-start_time)
单线程下载网页:
import requests,time,threading
from hashlib import md5
result_list = {}
def down_load_pic(url):
req = requests.get(url)
m = md5(url.encode()) #把url转换为二进制md5下
file_name = m.hexdigest()+'.png' #拼接文件名
with open(file_name ,'wb') as fw:
fw.write(req.content)
# return file_name
result_list[file_name] = threading.current_thread()
url_list = ['http://www.nnzhp.cn/wp-content/uploads/2019/10/f410afea8b23fa401505a1449a41a133.png',
'http://www.nnzhp.cn/wp-content/uploads/2019/11/481b5135e75c764b32b224c5650a8df5.png',
'http://www.nnzhp.cn/wp-content/uploads/2019/11/b23755cdea210cfec903333c5cce6895.png',
'http://www.nnzhp.cn/wp-content/uploads/2019/11/542824dde1dbd29ec61ad5ea867ef245.png']
start_time = time.time()
for url in url_list:
down_load_pic(url)
end_time = time.time()
print(end_time - start_time)
#结果:4.439253807067871
多线程下载网页:
import requests,time,threading
from hashlib import md5
result_list = {}
def down_load_pic(url):
req = requests.get(url)
m = md5(url.encode()) #把url转换为二进制md5下
file_name = m.hexdigest()+'.png' #拼接文件名
with open(file_name ,'wb') as fw:
fw.write(req.content)
# return file_name
result_list[file_name] = threading.current_thread()
url_list = ['http://www.nnzhp.cn/wp-content/uploads/2019/10/f410afea8b23fa401505a1449a41a133.png',
'http://www.nnzhp.cn/wp-content/uploads/2019/11/481b5135e75c764b32b224c5650a8df5.png',
'http://www.nnzhp.cn/wp-content/uploads/2019/11/b23755cdea210cfec903333c5cce6895.png',
'http://www.nnzhp.cn/wp-content/uploads/2019/11/542824dde1dbd29ec61ad5ea867ef245.png']
start_time = time.time()
for url in url_list:
t = threading.Thread(target=down_load_pic,args=(url,)) #args是存参数的,如果里面只有一个参数的话,一定要在这个参数后面加一个逗号,因为是保存在元组里,如果不加逗号,它会默认为是字符串 应该写成:args=(url,)
t.start() while threading.activeCount()!=1: pass end_time = time.time() print(end_time - start_time) #结果:3.959226369857788
一个进程里面至少有一个线程,这个线程就是主线程。
主线程只是调度用的,它把子线程招来之后就完事了,因此如果要统计运行时间,必须要让主线程等待所有的子线程都执行完后再记录结束时间。
2、守护线程,什么是守护线程呢,就相当于你是一个国王(非守护线程),然后你有很多仆人(守护线程),这些仆人都是为你服务的,一但你死了,那么你的仆人都给你陪葬。
#主线程结束,守护线程立马死掉。
import threading,time
def down_load():
time.sleep(5)
print("运行完了")
for i in range(10):
t = threading.Thread(target=down_load)
t.setDaemon(True) #设置子线程为守护线程
t.start()
print('over')
3、线程锁,线程锁就是,很多线程一起在操作一个数据的时候,可能会有问题,就要把这个数据加个锁,同一时间只能有一个线程操作这个数据。
import threading
from threading import Lock
num = 0
lock = Lock()#申请一把锁
def run():
global num
lock.acquire()#加锁
num+=1
lock.release()#解锁
lis = []
for i in range(5):
t = threading.Thread(target=run)
t.start()
lis.append(t)
for t in lis:
t.join()
print('over',num)
4、线程锁,线程锁就是,很多线程一起在操作一个数据的时候,可能会有问题,就要把这个数据加个锁,同一时间只能有一个线程操作这个数据。
#多个线程操作同一个数据的时候,就得加锁
import threading
num = 0
lock = threading.Lock() #申请一把锁
def add():
global num
# lock.acquire()#加锁
# num+=1
# lock.release()#解锁 #不解锁,就会产生死锁,会一直在等待
with lock:#简写,用with也会帮你加锁,解锁
num+=1
for i in range(20):
t = threading.Thread(target=add,)
t.start()
while threading.activeCount() !=1:
pass