热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开启子进程方法一

文章目录各个进程之间有什么特点父进程和子进程的关系join同步控制Process属于multiprocess中的一个类例1:importosfrommultipr

文章目录

          • 各个进程之间有什么特点
          • 父进程和子进程的关系
          • join同步控制



Process属于multiprocess中的一个类
  • 例1:

import os
from multiprocessing import Process # 因为在内部做了一些操作所以可以直接拿到Process类,可以通过这个类启动进程
def func():print('子进程',os.getpid(), os.getppid())
if __name__ == '__main__': # 只在windouws操作系统要写这句话,再linux和mac系统上不用写。print('主进程', os.getpid(), os.getppid())p = Process(target = func) # 实例化Process类。创建进程对象。此时没有开启此进程,func函数再子进程中执行,而不是在主进程中执行。p.start() # 开启进程

运行结果

主进程 14668 11392 # 主进程的id成了子进程的父进程
子进程 7616 14668 # 子进程和主进程同时运行。

在这里插入图片描述

为什么要写if __name__ == '__main__':
在这里插入图片描述

各个进程之间有什么特点

  1. 异步
  2. 数据隔离
    数据隔离问题:进程直接的数据是不同的数据隔离问题:进程直接的数据是不同的

import os
import time
from multiprocessing import Process
count = 100
def func():global countcount -= 1print('子进程:', count)
if __name__ == '__main__':print('主进程', os.getpid(), os.getppid())p = Process(target=func)p.start()time.sleep(2)print('主进程:', count)

运行结果

主进程 14708 11392
子进程: 99
主进程: 100

在这里插入图片描述

import os
import time
from multiprocessing import Processcount = 100def func():global countcount -= 1print('子进程__name__:', __name__)print('>>>',__name__)if __name__ == '__main__':print('主进程', os.getpid(), os.getppid())p = Process(target=func)print('启动子进程')p.start()print('结束子进程')

运行结果

>>> __main__
主进程 7148 11392
启动子进程
结束子进程
>>> __mp_main__ # 由于windows执行子进程时执行了主进程中程序,所以打印了子进程的__name__,也就是子进程的空间名
子进程__name__: __mp_main__

父进程和子进程的关系

父进程只负责通知操作系统启动子进程
接下来的工作由操作系统接手,父进程继续执行
父进程执行完毕后并不会直接结束程序,
而是会等待所有的子进程都执行完毕之后才结束
父进程要负责回收子进程的资源。也就是告诉操作系统,子进程全部执行完毕,通知操作系统子进程全部执行完毕,叫操作系统释放命名空间或把变量清空等。只有主进程有权限通知操作系统的级别。

  • 例2:

from multiprocessing import Process
import time
def f(name):time.sleep(1)print('hello', name, time.ctime())
if __name__ == '__main__':p_list = []for i in range(3):p = Process(target=f, args=('laura',))p_list.append(p)p.start()for i in p_list:i.join()print('end')

运行结果:

hello laura Sat Sep 22 11:21:47 2018
hello laura Sat Sep 22 11:21:47 2018
hello laura Sat Sep 22 11:21:47 2018
end

实例:
原生socket写并发程序

server端
import socketsk = socket.socket() # sk对象
sk.bind(('127.0.0.1', 9000))
sk.listen()
while True: # 循环接收连接conn, addr = sk.accept() # 此时conn可以通信了。while True: # 一直和别人send,recv,别人一直想和我连,我一直和另外一个人说话,这样就不能收到连接了。因为在里面的while True 不出来,外面的while True就执行不了了。conn.send(b'hello')print(conn.recv(1024))# 解决方法:把跟别人聊天这件事情交给一个子进程做,这样第一个循环就可以实现了。from multiprocessing import Processdef communicate(conn):while True:conn.send(b'hello')print(conn.recv(1024))if __name__ == '__main__':sk = socket.socket()sk.bind(('127.0.0.1', 9000))sk.listen()while True: conn, addr = sk.accept() Process(target=communicate, args=(conn,)).start() # 由于这句是在主进程写的,并且不希望在子进程中循环下去。所以要加一个if __name__ == '__main__'

在这里插入图片描述

client端
import socket
sk = socket.socket()
sk.connect(('127.0.0.1', 9000))
while True:print(sk.recv(1024)) # 那边先send,所以先recievesk.send(b'bye')

join同步控制

join属于Process类中的一个方法
模拟十个进程分别发送十封邮件

import time
import random
from multiprocessing import Process
def func(index):time.sleep(random.random()) # 0到1秒直接随机睡一会儿print('第%s个邮件已经发送完毕' % index)if __name__ == '__main__':for i in range(10):Process(target=func, args=(i, )).start() # 十个子进程异步执行,让十个进程分别发十个邮件。print('10个邮件已经发送完毕') # 最为主进程我想知道我的十个进程已经执行完了

运行结果

10个邮件已经发送完毕
4个邮件已经发送完毕
0个邮件已经发送完毕
8个邮件已经发送完毕
2个邮件已经发送完毕
7个邮件已经发送完毕
9个邮件已经发送完毕
5个邮件已经发送完毕
1个邮件已经发送完毕
3个邮件已经发送完毕
6个邮件已经发送完毕

由于主进程和子进程完全异步,所以同时打印出来了,如图
在这里插入图片描述
可我要的结果是子进程全部执行完了再打印这句话。
Procee类中的join方法能够帮助我们知道子进程是什么时候结束的。作用:阻塞直到p进程执行完毕就结束阻塞。
用join方法实现同步控制

import time
import random
from multiprocessing import Process
def func(index):time.sleep(random.randint(1, 3)) print('第%s个邮件已经发送完毕' % index)if __name__ == '__main__':p = Process(target=func, args=(1, ))p.start()p.join()print('1个邮件已经发送完毕')

运行结果

1个邮件已经发送完毕
1个邮件已经发送完毕

在这里插入图片描述

现在让十个进程异步发邮件,所有进程发完邮件后,才打印所有邮件发送完毕。相当于主进程和n个子进程同步了。
join在哪个进程下面就会在等待哪个进程。

import time
import random
from multiprocessing import Processdef func(index):time.sleep(random.random())print('第%s个邮件已经发送完毕' % index)if __name__ == '__main__':p_list = []for i in range(10):p = Process(target=func, args=(i, ))p.start()p_list.append(p)for p in p_list:p.join() # 十个进程都开启了之后,这十个进程都要执行完才执行以下代码。print('10个邮件已经发送完毕') # 一定是在最后才打印这句话

运行结果

2个邮件已经发送完毕
4个邮件已经发送完毕
1个邮件已经发送完毕
9个邮件已经发送完毕
3个邮件已经发送完毕
6个邮件已经发送完毕
7个邮件已经发送完毕
5个邮件已经发送完毕
8个邮件已经发送完毕
0个邮件已经发送完毕
10个邮件已经发送完毕

例:输出资源,屏幕为进程间共享资源时。

from multiprocessing import Process, Lock
import time
def f(l, i):# with l: # 加把锁把屏幕控制了,谁先拿到锁谁先在屏幕输出。相当于串行 # 加了with就不用l.acquire()和l.realease()了l.acquire()time.sleep(1) # 运行了10秒,如果没有锁,运行时间不用1秒print('hello world %s' % i)l.release()if __name__ == '__main__':print(time.time())lock = Lock()list1 = []for num in range(10):p = Process(target=f, args=(lock, num))p.start()list1.append(p)for i in list1:i.join()print(time.time())

运行结果

1537682507.537764
hello world 0
hello world 1
hello world 2
hello world 3
hello world 4
hello world 5
hello world 6
hello world 8
hello world 7
hello world 9
1537682517.8930845


推荐阅读
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • importjava.util.ArrayList;publicclassPageIndex{privateintpageSize;每页要显示的行privateintpageNum ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
author-avatar
宝宝彪恒
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有