Pycharm(十八)进程相关内容

一、多任务

概述:

多任务指的是 多个任务同时进行。

目的:

节约资源,充分利用CPU资源,提高效率。

表现形式:

并发:针对于单核CPU来讲的,如果有多个任务同时请求执行,当时同一瞬间CPU只能执行1个任务,于是就安排它们交替执行.因为时间间额非常短(CPU执行速度太快了),我们看起来好像是同时执行的,实际上并不是。

并行:针对多核CPU来讲的,多个任务可以同时执行。

进程介绍:

概述:

进程:指的是 可执行程序,是CPU分配资源的最小单位。

线程:进程的执行路径,执行单元。

通俗解释:

进程:车 线程:车道

多进程实现步骤:

1.导包

2.创建进程对象,关联:该进程要执行的任务。

3.启动进程

二、单进程程序

只有前边的内容执行结束之后,才会执行后续的内容,相对耗时,且没有做到资源的合理利用。

示例代码:

python 复制代码
"""
案例:
    回顾单进程程序, 即: 以前写的代码都是单进程的, 只有前边的内容执行结束后, 才会执行后续会的内容, 相对耗时, 且没有做到资源的合理利用.
"""
import time

# 需求: 模拟一遍写代码, 一遍听音乐.

# 1. 定义函数, 表示: 写代码.
def coding():
    for i in range(1, 11):
        time.sleep(0.1)
        print(f"正在写代码... {i}")


# 2. 定义函数, 表示: 听音乐.
def music():
    for i in range(1, 11):
        time.sleep(0.1)
        print(f"正在听音乐------ {i}")


# 3. 在main函数中测试.
if __name__ == '__main__':
    # 4. 模拟单进程程序.
    coding()
    music()

运行结果:

正在写代码... 1

正在写代码... 2

正在写代码... 3

正在写代码... 4

正在写代码... 5

正在写代码... 6

正在写代码... 7

正在写代码... 8

正在写代码... 9

正在写代码... 10

正在听音乐------ 1

正在听音乐------ 2

正在听音乐------ 3

正在听音乐------ 4

正在听音乐------ 5

正在听音乐------ 6

正在听音乐------ 7

正在听音乐------ 8

正在听音乐------ 9

正在听音乐------ 10

三、多进程程序

示例代码:

python 复制代码
"""
案例:
    回顾单进程程序, 即: 以前写的代码都是单进程的, 只有前边的内容执行结束后, 才会执行后续会的内容, 相对耗时, 且没有做到资源的合理利用.

多进程的实现步骤:
    1. 导包
    2. 创建进程对象, 关联: 要执行的函数.
    3. 启动进程.
"""
import multiprocessing, time

# 需求: 模拟一遍写代码, 一遍听音乐.

# 1. 定义函数, 表示: 写代码.
def coding():
    for i in range(1, 21):
        # 为了让效果更明显, 加入: 休眠线程.
        time.sleep(0.01)
        print(f"正在写代码... {i}", end='\n')


# 2. 定义函数, 表示: 听音乐.
def music():
    for i in range(1, 21):
        # 为了让效果更明显, 加入: 休眠线程.
        time.sleep(0.01)
        print(f"正在听音乐------ {i}")


# 3. 在main函数中测试.
if __name__ == '__main__':
    # 4. 创建两个进程对象, 分别关联上述的两个函数.
    p1 = multiprocessing.Process(target=coding)
    p2 = multiprocessing.Process(target=music)

    # 5. 启动进程.
    p1.start()
    p2.start()

运行结果:

正在听音乐------ 1

正在写代码... 1

正在听音乐------ 2

正在写代码... 2

正在听音乐------ 3

正在写代码... 3

正在听音乐------ 4

正在写代码... 4

正在听音乐------ 5

正在写代码... 5

正在听音乐------ 6

正在写代码... 6

正在听音乐------ 7

正在写代码... 7

正在听音乐------ 8

正在写代码... 8

正在听音乐------ 9

正在写代码... 9

正在听音乐------ 10

正在写代码... 10

正在听音乐------ 11

正在写代码... 11

正在听音乐------ 12

正在写代码... 12

正在听音乐------ 13

正在写代码... 13

正在听音乐------ 14

正在写代码... 14

正在听音乐------ 15

正在写代码... 15

正在听音乐------ 16

正在写代码... 16

正在听音乐------ 17

正在写代码... 17

正在听音乐------ 18

正在写代码... 18

正在听音乐------ 19

正在写代码... 19

正在听音乐------ 20

正在写代码... 20

四、带参数的多进程程序

python 复制代码
"""
案例:
    回顾单进程程序, 即: 以前写的代码都是单进程的, 只有前边的内容执行结束后, 才会执行后续会的内容, 相对耗时, 且没有做到资源的合理利用.

多进程的实现步骤:
    1. 导包
    2. 创建进程对象, 关联: 要执行的函数.
    3. 启动进程.

进程的参数解释, 即: multiprocessing模块的 Process类的 的参数:
    target: 用于关联 进程要执行的任务的.
    name:   进程名, 默认是: Process-1, Process-2,......Process-n, 可以手动修改, 一般不改.
    args:   可以通过 元组 的形式传递参数, 实参的个数 及 对应的数据类型 要和 形参的个数及类型 一致.
    kwargs: 可以通过 字典 的形式传递参数, 实参的个数 要和 形参的个数 一致.
"""
import multiprocessing, time


# 需求: 使用多进程来模拟小明一边写num行代码, 一边听count首音乐.
# 1. 小明写num行代码
def code(name, num):
    for i in range(1, num):
        # 为了让效果更明显, 加入: 休眠线程.
        time.sleep(0.01)
        print(f"{name} 正在写第 {i} 行代码... ")


# 2. 小明听count首音乐
def music(name, count):
    for i in range(1, count):
        # 为了让效果更明显, 加入: 休眠线程.
        time.sleep(0.01)
        print(f"{name} 正在听第 {i} 首音乐------ ")


# 3. 在main函数中编写测试代码.
if __name__ == '__main__':

    # 4. 创建进程对象.
    p1 = multiprocessing.Process(target=code, args=("小明", 20), name='QQ进程')
    # print(f'p1进程的名字: {p1.name}')
    p2 = multiprocessing.Process(target=music, kwargs={'count': 20, 'name': '小明'}, name='微信进程')
    # print(f'p2进程的名字: {p2.name}')

    # 5. 启动进程.
    p1.start()
    p2.start()

运行结果:

小明 正在写第 1 行代码...

小明 正在写第 2 行代码...

小明 正在听第 1 首音乐------

小明 正在写第 3 行代码...

小明 正在听第 2 首音乐------

小明 正在写第 4 行代码...

小明 正在听第 3 首音乐------

小明 正在写第 5 行代码...

小明 正在听第 4 首音乐------

小明 正在写第 6 行代码...

小明 正在听第 5 首音乐------

小明 正在写第 7 行代码...

小明 正在听第 6 首音乐------

小明 正在写第 8 行代码...

小明 正在听第 7 首音乐------

小明 正在写第 9 行代码...

小明 正在听第 8 首音乐------

小明 正在写第 10 行代码...

小明 正在听第 9 首音乐------

小明 正在写第 11 行代码...

小明 正在听第 10 首音乐------

小明 正在写第 12 行代码...

小明 正在听第 11 首音乐------

小明 正在写第 13 行代码...

小明 正在听第 12 首音乐------

小明 正在写第 14 行代码...

小明 正在听第 13 首音乐------

小明 正在写第 15 行代码...

小明 正在听第 14 首音乐------

小明 正在写第 16 行代码...

小明 正在听第 15 首音乐------

小明 正在写第 17 行代码...

小明 正在听第 16 首音乐------

小明 正在写第 18 行代码...

小明 正在听第 17 首音乐------

小明 正在写第 19 行代码...

小明 正在听第 18 首音乐------

小明 正在听第 19 首音乐------

五、获取进程的id

python 复制代码
"""
案例:
    获取进程的id

进程的ID介绍:
    概述:
        在操作系统中, 每个进程都有自己唯一的ID, 且当前进程被终止时, 该ID会被回收, 即: ID是可以重复使用的.
    目的:
        1. 查找子进程是由那个父进程创建的, 即: 找子进程和父进程的ID.
        2. 方便我们维护进程, 例如: kill -9 pid值 可以强制杀死进程.
    获取进程id的方式:
        获取当前进程的ID:
            方式1: os模块的 getpid()方法
            方式2: multiprocessing模块的 pid属性
        获取当前进程的父进程的pid:
            os模块的 getppid()方法   parent process: 父进程
结论:
    我们看到 p1, p2进程的父进程是main, main进程的父进程是Pycharm.exe
"""
# 导包
import multiprocessing, time, os


# 案例: 小明一边敲着第n行代码, 一边听着第n首音乐.
# 1. 定义函数, 表示: 敲代码.
def code(name, num):
    for i in range(1, num + 1):
        print(f'{name} 正在敲第 {i} 行代码...')
        time.sleep(0.1)
        # multiprocessing模块的current_process()函数: 获取当前进程对象
        print(f'当前进程(p1)的id: {os.getpid()}, {multiprocessing.current_process().pid}, 父进程的id为: {os.getppid()}')


# 2. 定义函数, 表示: 听音乐
def music(name, count):
    for i in range(1, count + 1):
        print(f'{name} 正在听第 {i} 首音乐.........')
        time.sleep(0.1)
        print(f'当前进程(p2)的id: {os.getpid()}, {multiprocessing.current_process().pid}, 父进程的id为: {os.getppid()}')


# 在main中测试.
if __name__ == '__main__':
    # 3. 创建进程对象.
    # Process类的参数: target: 关联的函数名, name: 当前进程的名字, args:元组的形式传参. kwargs: 字典的形式传参.
    p1 = multiprocessing.Process(name='Process_QQ', target=code, args=('乔峰', 10))
    p2 = multiprocessing.Process(name='Process_Wechat', target=music, kwargs={'count': 10, 'name': '虚竹'})

    # print(f"p1进程的名字: {p1.name}")
    # print(f"p2进程的名字: {p2.name}")

    # 4. 启动进程.
    p1.start()
    p2.start()

    print(f'当前进程(main)的id: {os.getpid()}, {multiprocessing.current_process().pid}, 父进程的id为: {os.getppid()}')

运行结果:

当前进程(main)的id: 37732, 37732, 父进程的id为: 42048

乔峰 正在敲第 1 行代码...

虚竹 正在听第 1 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 2 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 2 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 3 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 3 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 4 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 4 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 5 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 5 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 6 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 6 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 7 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 7 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 8 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 8 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 9 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 9 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

乔峰 正在敲第 10 行代码...

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

虚竹 正在听第 10 首音乐.........

当前进程(p1)的id: 44724, 44724, 父进程的id为: 37732

当前进程(p2)的id: 46024, 46024, 父进程的id为: 37732

六、进程之间数据相互隔离

python 复制代码
"""
案例:
    演示进程之间数据是相互隔离的.

关于进程, 你要记忆的内容:
    1. 进程之间数据是相互隔离的.   例如: 微信(进程) 和 QQ(进程)之间, 数据就是相互隔离的.
    2. 默认情况下, 主进程会等待它所有的子进程 执行结束再结束.

细节:
    多进程之间, 针对于 main进程的(外部资源), 每个子进程都会拷贝一份, 进行执行.
"""
import multiprocessing, time

# 需求: 定义1个列表, 然后定义两个函数, 分别往列表中添加数据, 获取数据. 之后用两个进程关联这个两个函数, 启动进程并观察结果.
# 1. 定义全局变量 my_list
my_list = []
print('我是main外资源, 看看我执行了几遍!')

# 2. 定义函数, 实现往列表中添加数据.
def write_data():
    for i in range(1, 6):
        # 具体的添加元素的动作
        my_list.append(i)
        # 打印添加动作.
        print(f'添加 {i} 成功!')
    # 细节: 添加数据完毕后, 打印结果.
    print(f'write_data函数: {my_list}')

# 3. 定义函数, 实现从列表中获取数据.
def read_data():
    # 休眠 3 秒, 确保 write_data函数执行完毕.
    time.sleep(3)
    # 打印结果.
    print(f'read_data函数: {my_list}')


# 在main中测试
if __name__ == '__main__':
    # 4. 创建进程对象.
    p1 = multiprocessing.Process(target=write_data)
    p2 = multiprocessing.Process(target=read_data)

    # 5. 启动进程
    p1.start()
    p2.start()

    # print('我是main内资源, 看看我执行了几遍!')

运行结果:

我是main外资源, 看看我执行了几遍!

我是main外资源, 看看我执行了几遍!

我是main外资源, 看看我执行了几遍!

添加 1 成功!

添加 2 成功!

添加 3 成功!

添加 4 成功!

添加 5 成功!

write_data函数: [1, 2, 3, 4, 5]

read_data函数: []

七、主进程和子进程的生命周期

示例代码一:

python 复制代码
"""
案例:
    演示 主进程 和 子进程的 生命周期.

结论:
    1. 进程之间数据是相互隔离的.   例如: 微信(进程) 和 QQ(进程)之间, 数据就是相互隔离的.
    2. 默认情况下, 主进程会等待它所有的子进程 执行结束再结束.

问: 如果要实现主进程结束时, 子进程也同步结束, 怎么办?
答:
    1. 设置子进程为 守护进程.     类似于: 骑士(守护) 和 公主(非守护)
    2. 手动关闭子进程.
"""
import multiprocessing, time


# 需求: 设置子进程执行3秒, 主进程执行1秒, 观察效果.
# 1. 定义方法, 用于关联子进程的.
def my_method():
    for i in range(10):
        print(f'工作中... {i}')
        time.sleep(0.3)  # 总休眠时间 = 0.3 * 10 = 3秒


# 2. 在main方法中测试.
if __name__ == '__main__':
    # 3. 创建子进程对象, 并启动.
    p1 = multiprocessing.Process(target=my_method)
    p1.start()  # 3秒后结束.

    # 4. 主进程执行1秒后结束.
    time.sleep(1)

    # 5. 打印主进程的结束提示.
    print('主进程 main 执行结束!')

运行结果:

工作中... 0

工作中... 1

工作中... 2

主进程 main 执行结束!

工作中... 3

工作中... 4

工作中... 5

工作中... 6

工作中... 7

工作中... 8

工作中... 9

示例代码二:

python 复制代码
"""
案例:
    演示 主进程 和 子进程的 生命周期.

结论:
    1. 进程之间数据是相互隔离的.   例如: 微信(进程) 和 QQ(进程)之间, 数据就是相互隔离的.
    2. 默认情况下, 主进程会等待它所有的子进程 执行结束再结束.

问: 如果要实现主进程结束时, 子进程也同步结束, 怎么办?
答:
    1. 设置子进程为 守护进程.     类似于: 骑士(守护) 和 公主(非守护)
    2. 手动关闭子进程.
"""
import multiprocessing, time


# 需求: 设置子进程执行3秒, 主进程执行1秒, 观察效果.
# 1. 定义方法, 用于关联子进程的.
def my_method():
    for i in range(10):
        print(f'工作中... {i}')
        time.sleep(0.3)  # 总休眠时间 = 0.3 * 10 = 3秒


# 2. 在main方法中测试.
if __name__ == '__main__':
    # 3. 创建子进程对象, 并启动.
    p1 = multiprocessing.Process(target=my_method)
    # 方式1: 设置子进程p1为守护进程, 非守护进程是: main进程, 所以: 当main进程关闭的时候, 它的守护进程也会关闭.
    # p1.daemon = True
    p1.start()  # 3秒后结束.

    # 4. 主进程执行1秒后结束.
    time.sleep(1)

    # 方式2: 手动关闭子进程.
    # 会导致子进程变成僵尸进程, 即: 不会立即释放资源.
    # 而是交由init进程接管(充当新的父进程), 在合适的时机释放资源.
    p1.terminate()      # 不推荐使用.

    # 5. 打印主进程的结束提示.
    print('主进程 main 执行结束!')

运行结果:

工作中... 0

工作中... 1

工作中... 2

主进程 main 执行结束!

相关推荐
__如风__8 小时前
onlyoffice文档转换服务离线部署
python
今晚务必早点睡8 小时前
写一个Python接口:发送支付成功短信
开发语言·python
ada7_8 小时前
LeetCode(python)22.括号生成
开发语言·数据结构·python·算法·leetcode·职场和发展
2501_941871458 小时前
面向微服务链路追踪与全局上下文管理的互联网系统可观测性设计与多语言工程实践分享
大数据·数据库·python
luoluoal8 小时前
基于python的语音和背景音乐分离算法及系统(源码+文档)
python·mysql·django·毕业设计·源码
love530love8 小时前
EPGF 新手教程 12在 PyCharm(中文版 GUI)中创建 Poetry 项目环境,并把 Poetry 做成“项目自包含”(工具本地化为必做环节)
开发语言·ide·人工智能·windows·python·pycharm·epgf
cute_ming8 小时前
从 Node.js + TypeScript 无缝切换到 Python 的最佳实践
python·typescript·node.js
2501_941870568 小时前
从配置频繁变动到动态配置体系落地的互联网系统工程实践随笔与多语言语法思考
java·前端·python
西西弗Sisyphus9 小时前
Python FastAPI 和 Uvicorn 同步 (Synchronous) vs 异步 (Asynchronous)
python·fastapi·uvicorn
MistaCloud9 小时前
Pytorch深入浅出(十三)之模型微调
人工智能·pytorch·python·深度学习