Python学习笔记(二十四):在 linux 系统下使用 fork() 创建子进程


进程:

编写完毕的代码,在没有运行的时候,称之为程序;

正在运行的代码,就称之为进程;

进程,除了包含代码以外,还有需要运行的环境等,所以和程序是有区别的;

 

fork() 方法创建子进程:

Python 的 os 模块,封装了常见的系统调用,其中就包括 fork(),可以在 python 程序中轻松的创建子进程;

注意:fork() 方法只能用在类 linux 系统下,不能用在 windows 系统下;

先看下面一段代码:

# 导入 os 模块
import os

# 调用 fork() 方法创建子进程
os.fork()
print("hello")

输出结果:

可以发现,代码里只有一个输出语句,但是实际上输出了两次;

这是因为:

  • 程序执行到 os.fork() 时,操作系统会创建一个新的进程(子进程),然后复制父进程的所有信息到子进程中;

  • 然后父进程和子进程都会从 fork() 函数中得到一个返回值,子进程永远返回 0,而父进程返回子进程的 id 号;

将上面代码改成如下所示:

# 导入 os 模块
import os

# 调用 fork() 方法创建子进程,并获取返回值
pid = os.fork()

# 输出 fork() 方法返回的值
print("pid:", pid)

输出结果为:

如果子进程中有耗时的操作,当父进程先执行结束的时候,虽然程序看似已经结束了,但是子进程并不会立刻结束,而是等子进程中的代码执行完毕之后才会结束:

import os
import time

# 调用 fork() 方法创建子进程,并获取返回值
pid = os.fork()

# 输出 fork() 方法返回的值
print("pid:", pid)

# 在子进程中模拟耗时操作
if (pid == 0):
    print("=== 子进程开始 ===")
    time.sleep(2)   # 延迟 2 秒
    print("=== 子进程结束 ===")
else:
    print("=== 父进程 ===")

输出结果:

 

os.getpid() 和 os.getppid():

getpid():获取当前进程的 id(get process id);

getppid():获取父进程的 id(get parent process id);

# 导入 os 模块
import os

# 调用 fork() 方法创建子进程,并获取返回值
pid = os.fork()

# 输出 fork() 方法返回的值
print("pid:", pid)

# os.getpid():获取当前进程 id
# os.getppid():获取父进程 id
if (pid > 0):
    print("父进程:", os.getpid())
else:
    print("子进程:%d === 父进程:%d" %(os.getpid(), os.getppid()))

输出结果:

 

多进程修改全局变量:

多进程中,每个进程中所有数据(包括全局变量)都各自拥有一份,互不影响;即多进程数据不共享;

import os
import time

# 定义一个全局变量
num = 10

# 创建子进程
pid = os.fork()

if (pid == 0):
    # 在子进程中改变 num 的值
    num += 10
    print("子进程:", num)
else:
    # 延迟 1 秒,是为了保证子进程一定先执行完毕
    time.sleep(1)
    print("父进程:", num)

输出结果:

 

多个 fork() 的情况:

先看下面一段代码:

import os

# 第一次使用 fork 创建子进程
pid = os.fork()
if pid == 0:
    print("=== 1 ===")
else:
    print("=== 2 ===")

# 第二次使用 fork 创建子进程
pid = os.fork()
if pid == 0:
    print("=== 11 ===")
else:
    print("=== 22 ===")

输出结果:

原理分析:

  • 当程序运行到 “第一次使用 fork 创建子进程时”,此时有两个进程,一个父进程,一个子进程;

  • 我们知道,程序在创建子进程的时候,会把父进程中的所有信息全部复制到子进程中;那么就是说 “第二次使用 fork 创建子进程” 的代码,在父进程和子进程中各有一份;

  • 所以,当父进程执行到 “第二次使用 fork 创建子进程” 的时候,又创建了一个子进程,就是说一个父进程创建了两个子进程;此时会输出一遍 11 和 22;

  • 而当 “第一次使用 fork 创建的子进程” 也执行到 “第二次使用 fork 创建子进程” 时,子进程又创建了一个孙子进程,那么理所当然的子进程就变成了孙子进程的父进程;那么此时又会再输出一遍 11 和 22;

  • 所以 11 和 22 总共输出了两次;

  • 程序中总共有 4 个进程,分别是父进程,大儿子进程,二儿子进程,以及大儿子进程的子进程;

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值