多线程
1、多线程、多进程
1、线程是程序里面最小的执行单元。
2、进程是资源的集合。
线程是包含在一个进程里面的, 一个进程可以有多个线程。
一个进程里面默认有一个线程。
主线程
默认有个主线程
子线程:
主线程启动子线程
1、如果这个函数里面有返回值的话,怎么获取呢?
子线程运行的函数,如果里面有返回值的话,是不能获取到的
只能在外面定义一个list或者字典来存每次处理的结果。
电脑CPU有几核,那么只能同时运行几个线程。
但是呢,python的多线程,只能利用一个CPU的核心。
GIL 全局解释器锁。
2、锁呢就是,在多个线程同时修改一个数据的时候,可能会把数据覆盖,在python2里面需要加锁。
python3里面不加锁也无所谓,默认会自动帮你加锁。
3、守护线程。
只要主线结束,那么子线程立即结束,不管子线程有没有运行完成。
多进程
多用于处理CPU密集型任务
多线程
多用于IO密集型任务
Input Ouput
import threading,time,json
import requests,time
def run():
time.sleep(3)
print('哈哈哈')
for i in range(5):
run() #串行
for i in range(5):
t = threading.Thread(target=run) #实例化线程,只写函数名
t.start()
主程序:
urls = {
'besttest':'http://www.besttest.cn',
'niuniu':'http://www.nnzhp.cn',
'cc':'http://www.cc-na.cn',
'dsx':'http://www.imdsx.cn',
'alin':'http://www.limlhome.cn'
}
data={}
def down_html(file_name,url):
start_time1 = time.time()
req = requests.get(url).content #content 返回的是二进制文件
open(file_name+'.html','wb').write(req) #wb
open(file_name,'wb')
end_time1 = time.time()
run_time1 = end_time1 - start_time1
print('下载用时:', run_time1)
data[url]=run_time1
#1、并行
实际运行6个线程,进程里面有一个线程,这个线程交主线程
start_time=time.time()
threads = []
for k,v in urls.items():
t = threading.Thread(target=down_html,args=(k,v)) #多线程传参的时候必须用args
t.start()
threads.append(t)
for k in threads:
k.join()
end_time = time.time()
run_time = end_time-start_time
print('下载用时:',run_time)
# #2、串行
#总的时间,包含了主线程运行时间
start_time=time.time()
for k,v in urls.items():
down_html(k,v)
end_time = time.time()
run_time = end_time-start_time
print('下载用时:',run_time)
print(data)
多线程等待
import threading,time
def run():
time.sleep(4)
print('哈哈哈')
start_time = time.time()
threads = [] #存放启动的5个线程
for i in range(5):
t = threading.Thread(target=run)
t.start()
threads.append(t)
# t.join() #主线程等待子线程执行结束
print('threads:',threads)
for t in threads:
t.join() 主线程循环等待子线程执行结束
end_time = time.time()
print('时间是:',end_time-start_time)
守护线程
import threading,time
def run():
time.sleep(3)
print('哈哈哈')
for i in range(50):
t = threading.Thread(target=run)
t.setDaemon(True) #把子线程设置成为守护线程,主线程结束时,守护的线程也会里面结束
t.start()
print('Done,运行完成。')
time.sleep(3)
多进程
import multiprocessing,threading
def run():
print('哈哈哈哈')
def my(num):
for i in range(num):
t = threading.Thread(target=run)
t.start()
if __name__ == '__main__':
for i in range(5):
p = multiprocessing.Process(target=my,args=(6,))
启动一个进程,然后调用的时my函数,args =(6,)传入的参数,如果这里时一个值那么必须加个逗号,写成 (6,)
print('第%s进程' % i)
p.start()
线程锁
import threading,time
num = 1
lock = threading.Lock() #申请一把锁
def run():
time.sleep(1)
global num
lock.acquire() #加锁
num+=1
lock.release() #解锁
ts = []
for i in range(100):
t = threading.Thread(target=run) #启动多线程run,
t.start()
ts.append(t)
[t.join() for t in ts]
print(num)