Python 多任务 —— 进程
程序员文章站
2022-06-08 16:28:18
...
高级编程技巧 学习笔记
一、进程
1.1、进程与程序
-
进程: 正在执行的代码 + 用到的资源
-
程序: 没有执行的代码,是一个静态的 exe 文件
1.2、进程的状态
1.3、使用进程实现多任务
multiprocessing 模块 就是跨平台的多进程模块,提供了一个 Process 类 来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另外的事情。
# 创建一个进程与创建线程非常相似
# 可以分别执行 线程 与 进程 , 在任务管理器中查看一下区别
import multiprocessing
import time
import threading
def demo():
while True:
print("--1--")
time.sleep(1)
def demo1():
while True:
print("--2--")
time.sleep(1)
def main():
p1 = multiprocessing.Process(target=demo)
p2 = multiprocessing.Process(target=demo1)
# t1 = threading.Thread(target=demo)
# t2 = threading.Thread(target=demo1)
p1.start()
p2.start()
# t1.start()
# t2.start()
if __name__ == '__main__':
main()
-
线程实现多任务,是在一个代码文件里面执行
-
进程实现多任务,相当于复制一整份代码文件来执行子进程
1.4、进程与线程之间的对比
-
进程: 能够完成多任务,一台电脑上可以同时运行多个QQ
-
线程: 能够完成多任务,一个QQ中的多个聊天窗口(先有进程,再有线程)
-
根本区别: 进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
二、进程间通信 - Queue
2.1、Queue(队列)
- 先进先出
from multiprocessing import Queue
# 创建队列 最多可以存放3条数据
q = Queue(3)
# 存数据
q.put(1)
q.put("juran")
q.put([11, 22])
# 队列大小
print(f'队列大小: {q.qsize()}')
# 判断队列是否已满
print(f'队列是否已满: {q.full()}')
# 队列已满, 堵塞
# q.put({"name": "juran"})
# 不阻塞, 直接抛出异常
# q.put_nowait({"name": "juran"})
# 取数据
print('\n取出数据: ')
print(q.get())
print(q.get())
print(q.get())
print()
# 队列没有数据, 堵塞
# print(q.get())
# 不阻塞, 直接抛出异常
# print(q.get_nowait())
# 判断队列是否为满
print(f'队列是否已满: {q.full()}')
# 判断队列是否为空
print(f'队列是否为空: {q.empty()}')
2.2、使用队列实现进程间的通信
- 边下载边保存
import multiprocessing
import time
def download(q):
"""下载数据"""
lis = [11, 22, 33]
for item in lis:
q.put(item)
print("下载到队列完成, 开始保存...\n")
def analysis(q):
"""数据处理"""
analysis_data = list()
# 不知道队列大小, 取完为止
while True:
data = q.get()
print(f'添加 {data}')
analysis_data.append(data)
# 队列为空则退出
if q.empty():
break
print(f'保存完成: {analysis_data}')
def main():
# 创建一个队列 跨进程通信的队列
# q = multiprocessing.Queue(2)
# 不确定下载到队列的数据个数, 可以不填数值
q = multiprocessing.Queue()
t1 = multiprocessing.Process(target=download, args=(q, ))
t2 = multiprocessing.Process(target=analysis, args=(q, ))
t1.start()
time.sleep(1)
t2.start()
if __name__ == '__main__':
main()
2.3、注意还有一个队列
- from queue import Queue (普通队列,不能实现多线程)
- from multiprocessing import Queue (实现多线程的队列)
from queue import Queue
import multiprocessing
def demo1(q):
q.put('a')
def demo2(q):
data = q.get()
print(data)
if __name__ == '__main__':
# 普通的队列
q = Queue()
# 实现多进程的队列
# q = multiprocessing.Queue()
t1 = multiprocessing.Process(target=demo1, args=(q,))
t2 = multiprocessing.Process(target=demo2, args=(q,))
# 会报错
t1.start()
t2.start()
# 要想代码跑起来, 得用 run(), 但这已经不是多线程了
# t1.run()
# t2.run()
三、多进程共享全局变量
- 进程是不共享的,线程是共享的
import multiprocessing
import threading
a = 1
def demo1():
global a
a += 1
def demo2():
print(a)
if __name__ == '__main__':
# 进程
t1 = multiprocessing.Process(target=demo1)
t2 = multiprocessing.Process(target=demo2)
# 线程
# t1 = threading.Thread(target=demo1)
# t2 = threading.Thread(target=demo2)
t1.start()
t2.start()
上一篇: ThinkPHP敏感词汇过滤
下一篇: 实现三栏布局的三种方法