import time
from multiprocessing import Process
def func(a,b,c):
time.sleep(1)
print(a,b,c)
if __name__ == '__main__':
Process(target=func,args=(1,2,3)).start() #这里的target是目标的意思,固定搭配
Process(target=func,args=(2,3,4)).start() #所有的Process()都是子进程,子进程都放在if下。
Process(target=func,args=(3,4,5)).start()
需要注意:args是传值,若只传一个值时,必须为元组形式。
p.start() #P是一个进程操作
p.terminate()终止进程
p.is_alive()进程是否存活
join(阻塞,直到P对应的进程结束后才结束阻塞-对子进程同步管理的方法)
示例:
import time
import random
from multiprocessing import Process
def send_mail(name):
time.sleep(random.uniform(1,3))
print('已经给%s发送邮件完毕'%name)
if __name__ == '__main__':
lst = ['alex','yuan','宝元','太白']
p = Process(target=send_mail, args=('alex',))
p.start()
p.join() # 阻塞,直到p对应的进程结束之后才结束阻塞
print('所有的信息都发送完毕了')
守护进程(p.daemon=True)
守护进程是一个子进程,守护的是主进程。
结束条件:主进程的代码结束,守护进程也结束
import time
from multiprocessing import Process
def func():
for i in range(20):
time.sleep(0.5)
print('in func')
def func2():
print('start : func2')
time.sleep(5)
print('end : func2')
if __name__ == '__main__':
p = Process(target=func)
p.daemon = True # 表示设置p为一个守护进程
p.start()
p2 =Process(target=func2)
p2.start()
print('in main')
time.sleep(3)
print('finished')
p2.join()
import os
import time
from threading import Thread
def func():
time.sleep(1)
print('in func',os.getpid())
print('in main',os.getpid())
for i in range(20):
# func()
Thread(target=func).start()
线程中的其他方法
from threading import active_count返回当前有多少个正在工作的线程
print(active_count())
from threading import enumerate,Thread
def func():
print('in son thread')
Thread(target=func).start()
print(enumerate()) 返回一个存储着所有存活线程对象的列表
线程没有terminate,不能强制结束,必须等所有的子线程结束后结束
守护线程
主线程会等待子线程结束才结束
守护线程会随着主线程的结束而结束
守护线程会守护主线程和所有的子线程
进程会随着主线程的结束而结束
import time
from threading import Thread
def daemon_func():
while True:
time.sleep(0.5)
print('守护线程')
def son_func():
print('start son')
time.sleep(5)
print('end son')
t = Thread(target=daemon_func)
t.daemon = True 设置守护
t.start()
Thread(target=son_func).start()
time.sleep(3)
print('主线程结束')
线程中的锁
数据不安全问题
在线程中也是会出现数据不安全问题(1.对全局变量进行修改 2.对某个值+= -= = /)
只能通过加锁来解决
递归锁
from threading import Rlock,Thread
可以连续加锁
池(帮助利用多核,批量处理任务)
进程池
好处:控制进程的数量,节省资源的开销
示例:
import os
import time
from concurrent.futures import ProcessPoolExecutor 线程池
# def make(i):
# time.sleep(1)
# print('%s 制作螺丝%s'%(os.getpid(),i))
# return i**2
#
# if __name__ == '__main__':
# p = ProcessPoolExecutor(4) # 创建一个进程池
# for i in range(100):
# p.submit(make,i) # 向进程池中提交任务
# p.shutdown() # 阻塞 直到池中的任务都完成为止
# print('所有的螺丝都制作完了')
# p.map(make,range(100)) # submit的简便用法
# 接收返回值
# ret_l = []
# for i in range(100):
# ret = p.submit(make,i)
# ret_l.append(ret)
# for r in ret_l:
# print(r.result())
# ret = p.map(make, range(100))
# for i in ret:
# print(i)
线程池
from urllib.request import urlopen
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
def get_html(name,addr):
ret = urlopen(addr)
return {'name':name,'content':ret.read()}
def parser_page(ret_obj):
dic = ret_obj.result()
with open(dic['name']+'.html','wb') as f:
f.write(dic['content'])
url_lst = {
'name':'url',
'name':'url',
'name':'url',
'name':'url',
'name':'url',
}
t = ThreadPoolExecutor(20)
for url in url_lst:
task = t.submit(get_html,url,url_lst[url])
task.add_done_callback(parser_page)