进程 线程 协程
并发: 一个cpu, 轮流交替进行多线程
并行: 多个cpu, 同时执行,或 同时并发执行
进程 > 线程 > 协程 > 生成器
都可以实现多任务: 与特点有关
- 任务比较多 用进程
- 爬虫 用线程 或 协程
进程(Process),操作系统结构的基础,
曾经,面向进程设计的计算机结构中,进程就是程序的基本执行实体.(一个c)
当代,面向线程设计的计算机结构中,进程是线程的容器
* 优点
* 缺点
- linux下 使用 fork 函数创建进程 os模块的fork
- windows 使用 multiprocessing模块
-
多进程 能否 访问 同一个全局变量?
- 能, 仅仅 复制 全局变量 到自己进程, 不共用
-
耗时用 线程 - 下载
-
计算用 进程 - 运算
import os
import time
from multiprocessing import Process
n = 5 #
def download(t):
global n # 只是取到全局n的初始值, 不与task_2 共用
while True:
n -= 1.8
print(' -- SonProcess Task 1', os.getpid(), '-', os.getppid(), 'n:', n)
time.sleep(t)
def getfile(t):
global n
while True:
n += 0.75
print(' -- SonProcess Task 2', os.getpid(), '-', os.getppid(), 'n:', n)
time.sleep(t)
if __name__ == '__main__':
print('MainProcess', n)
download# 错的
p_1 = Process(target=download, args=(1,)) # 进程的 声明
p_2 = Process(target=getfile, args=(2,))
p_1.start() # 进程的 祁东
p_2.start()
while n >= 0:
n -= 1
print('MainProcess', n) # 此时共3个进程: 主进程 子进程1 2
time.sleep(2)
p_2.terminate() # 子进程的 关闭
p_1.terminate()
# 主进程 运行到此, 关闭
自定义进程
import random
from multiprocessing import Process
from time import sleep
class MyProcess(Process):
def __init__(self, c_name): # 如果想 传入参数
super(MyProcess, self).__init__()
self.cname = c_name
# 重写 run 方法
def run(self):
n = 1
while True:
t = random.choice([0.3, 0.5, 0.8, 1])
print('进程:{} -- n: {} [{}] -- t:'.format(self.name, n, self.cname), t)
n += 1
sleep(t)
# self.name 自动命名
if __name__ == '__main__':
p0 = MyProcess('尚尚')
p1 = MyProcess('唐唐')
p0.start()
p1.start()
pool
子进程数量不多-> multiprocess 的 Process 动态生成即可
上千个子进程 -> multiprocess 的 pool 方法
初始化pool 指定 最大进程数, 新请求提交, 自动创建进程.
进程数达到最大值, 该请求等待 ( 网盘 多个文件同时下载)
阻塞式: 添加一个,执行一个. 执行结束后 返回个啥
非阻塞式: 一起添加到队列,立刻返回. 执行结束后, 回调 携带结果
pool.apply_async() 非阻塞模式 一起来
pool.apply() 阻塞模式 一个一个来
def task_1(task_name):
return retu_str
def call_back(n):
pass
if __name__ == '__main__':
pool = Pool(4)
tasks = ['吃饭', '睡觉', '打豆豆', '看书', '打代码', '啪啪啪-2', '吃饭饭2', '睡觉觉2', '打豆豆豆豆', '看书书', '打代码码码', '啪啪啪']
for i in tasks:
# pool.apply()
pool.apply_async(task_1, args=(i,), callback=call_back) # 非阻塞 异步
# 进程池 依赖于 主进程, 阻止main结束
pool.close() # 进程池 任务 结束
pool.join() # 阻止 主进程 结束
进程间通信 Queue队列
后面笔记 就乱写了, 贴代码吧
from multiprocessing import Queue
q = Queue(8)
q.put()
q.get()
q.full()
q.empty()
q.put_nowait()
q.get_nowait()
# queue
import random
import time
from multiprocessing import Queue, Process
def download(q):
for i in range(100):
t = random.random() * 2
f = str(i) + '.jpg'
print('- 正在下载 -- ', f)
time.sleep(t)
q.put(f)
print('-- 下载完成 -- ', f, ' 用时:', round(t, 2), 's')
def getfile(q):
while True:
if not q.empty():
time.sleep(1)
print('--- 获取文件 -- ', q.get(), ' 剩余文件', q.qsize(), '个')
if __name__ == '__main__':
q = Queue(5)
p_1 = Process(target=download, args=[q]) # 进程的 声明
p_2 = Process(target=getfile, args=[q])
p_1.start()
p_2.start()
p_1.join()
p_2.join()
p_2.terminate() # 子进程的 关闭
p_1.terminate()
# queue 依赖 主进程 运行到此, 释放了q