Python 多任务 —— 进程

高级编程技巧 学习笔记

一、进程


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、进程与线程之间的对比

扫描二维码关注公众号,回复: 8956319 查看本文章
  • 进程: 能够完成多任务,一台电脑上可以同时运行多个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()
发布了85 篇原创文章 · 获赞 0 · 访问量 1205

猜你喜欢

转载自blog.csdn.net/qq_43621629/article/details/104121313