进程:一个进程就是一个程序
线程:就是进程里面最小的执行单元
干活的是线程,一个进程里面有多个线程,最少有1个线程,每个线程之间都是互相独立的
没有真正意义上的并发,电脑几核 就能一起运行几个程序,因为cpu处理速度快,看起来像并发的
python里面的多线程,是利用不了多核cpu的,只能利用一个核心cpu,GIL 全局解释器锁(自行百度)
有些情况下,你用多线程,比用单线程还慢
多进程,它是可以利用多核cpu的
import threading,time
all_res = [] #定义全局变量,获取函数返回值,不能用return
def run(name):
print('子线程',threading.current_thread())
time.sleep(1)#等待1s
print('【%s】haha'%name)
name = 'hhk'+name
all_res.append(name)
threads = []#存放所有的子线程
for i in range(5):
t = threading.Thread(target=run,args=(str(i),)) #找线程干活 需要传参则args 元祖传参,只有一个参数后面需要有个逗号
t.start() #开始干活
threads.append(t)
# t.join()#等待主进程,我们一起走
print(threads)#优先打印,线程之间独立,主进程继续运行,可通过join让子线程等待主线程一起
也可以通过判断目前活跃线程数来判断子线程是否含在运行
import threading,time
all_res = [] #定义全局变量,获取函数返回值,不能用return
def run(name):
print('子线程',threading.current_thread())
time.sleep(1)#等待1s
print('【%s】haha'%name)
name = 'hhk'+name
all_res.append(name)
threads = []#存放所有的子线程
for i in range(5):
t = threading.Thread(target=run,args=(str(i),)) #找线程干活 需要传参则args 元祖传参,只有一个参数后面需要有个逗号
t.start() #开始干活
threads.append(t)
while threading.active_count()!=1:#活跃线程数不等于1,就等,直到只剩主线程
pass
print(threads)
线程池
import threadpool,pymongo,requests#第三方模块
client = pymongo.MongoClient(host='118.24.3.xx')
table = client['likun']['qq_group_likun']
all_qq = [i.get('qq') for i in table.find()]
print(all_qq)
url = "https://q4.qlogo.cn/g?b=qq&nk=%s&s=140"
def down_img(qq_num):
res = requests.get(url%qq_num).content
with open('%s.jpg'%qq_num, 'wb') as fw:
fw.write(res)
pool = threadpool.ThreadPool(200)#线程池的大小
all_request = threadpool.makeRequests(down_img,all_qq)#分配数据
for a in all_request:
pool.putRequest(a)#往线程池中加请求
# [pool.putRequest(a) for a in all_request]
pool.wait()#等待所有的线程运行完
多进程、进程池
#什么时候用多线程,什么是时候用多进程
# 多线程适用于io密集型任务
# 磁盘io,网络io
# 多进程适用于cpu密集型任务
# 排序
from multiprocessing import Process,Pool,active_children
import pymongo,requests
client = pymongo.MongoClient(host='118.24.3.xx',port=27017)
table = client['likun']['qq_group_likun']
all_qq = [i.get('qq') for i in table.find()]
url = 'http://q4.qlogo.cn/g?b=qq&nk=%s&s=140'
def down_img(qq_num):
res = requests.get(url%qq_num).content
with open('%s.jpg'%qq_num,'wb') as fw:
fw.write(res)
if __name__ == '__main__':
# for qq in all_qq:
# p = Process(target=down_img,args=(qq,))#多进程
# p.start()
# # print(active_children())
#
pool = Pool(20)#进程池大小
list(pool.map(down_img,all_qq))#运行。使用进程池
锁
import threading
from threading import Lock
num = 0
lock = Lock()#实例化一把锁,
#多个线程操作一份数据,最好加上锁
def run():
global num
# lock.acquire()#枷锁
# num+=1
# lock.release()#解锁
while num<1000:
with lock: #自动解锁了
num+=1
for i in range(100):
t = threading.Thread(target=run)
t.start()
print(num)