iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python网络编程之进程详解
  • 889
分享到

python网络编程之进程详解

2024-04-02 19:04:59 889人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录1.进程1.1进程:1.2在python中创建进程1.3 使用multiprocessing创建进程1.3.1 单个进程时: 1.3.2 多个子进程时:1.3.3 自定

1.进程

它们的主要作用:多任务同时执行

1.1进程:

windows打开的程序就是一个进程例如打开qq 打开微信

如果打开2个qq代表打开了2个进程

1.2在Python中创建进程

只能linux 使用os.fork()用这个可以创建多进程

Linux/Windows使用multiprocessing模块和Pool进程池(他俩是跨平台模块)

1.3 使用multiprocessing创建进程

1.3.1 单个进程时: 

from multiprocessing import Process #从multiprocessing库中导入Process模块
#执行进程代码
#一个子进程
def test(interval):
    print("我是一个子进程")
 
#执行主程序
def main():
    print("主进程启动")
    p = Process(target=test,args=(1,)) #使用进程模块,目标参数target为子进程函数
    p.start() #启动子进程
    print("主进程结束")
 
if __name__ == '__main__': 
    main()
"""
>>> runfile('D:/python_files/python_fiew/网络编程_01.py', wdir='D:/python_files/python_fiew')
主进程启动
主进程结束
我是一个子进程
"""

1.3.2 多个子进程时:

from multiprocessing import Process
import time,os
#子进程1
def child_1(interval):
    print("子进程(%s)开始执行,父进程为(%s)"%(os.getpid(),os.getpid())) #os.getpid()为获取进程号
    t_stat = time.time() #计时开始
    time.sleep(interval) #程序将被挂起n秒
    t_end = time.time() #计时结束
    print("子进程(%s)的执行时间为'%0.2f'秒"%(os.getpid(),t_end-t_stat))
#子进程2
def chlid_2(interval):
    print("子进程(%s)开始执行,父进程为(%s)"%(os.getpid(),os.getpid()))
    t_stat = time.time()
    time.sleep(interval)
    t_end = time.time()
    print("子进程(%s)的执行时间为(%0.2f)"%(os.getpid(),t_end-t_stat))
 
if __name__ == '__main__':
    print("-----父进程开始执行-------")
    print("父进程启动时,父进程PID为:(%s)"%(os.getpid()))  #打印父进程启动时父进程的PID
    p1 = Process(target=child_1,args=(1,)) #实例化子进程1
    p2 = Process(target=chlid_2,args=(1,)) #实例化子进程2
    p1.start() #启动子进程1
    p2.start() #启动子进程2
    #此时父进程仍然在执行
    print("pi.is_alive=%s"%(p1.is_alive()))  #p1.is_alive() 判断子进程p1是否还在执行,执行则返回ture
    print("p2_is_alive=%s"%(p2.is_alive()))
    #输出此时进程执行过程中的PID(进程号)
    print("执行过程中的p1的进程号p1.pid=%s"%(p1.pid))
    print("执行过程中的p2的进程号p2.pid=%s" % (p2.pid))
    print("---等待子进程结束----")
    p1.join() #等待子程序p1结束
    p2.join()
    print("父进程结束,此时父进程的进程号为:(%s)"%(os.getpid()))
#总结:#os.getpid()为获取进程号   #p1.is_alive() 判断子进程p1是否还在执行,执行则返回ture

由运行结果分析:子进程在执行的过程中,进程号不变。父进程号在启动时,和在结束所有子进程时 相同,而当子进程同时执行时,父进程号会动态变化。

      挂起进程在 操作系统中可以定义为暂时被淘汰出 内存的进程,机器的资源是有限的,在资源不足的情况下,操作系统对在内存中的程序进行合理的安排,其中有的进程被暂时调离出内存,当条件允许的时候,会被操作系统再次调回内存,重新进入等待被执行的状态即就绪态,系统在超过一定的时间没有任何动作。 

1.3.3 自定义进程类方法

使用Process子类创建进程Process(target=test)实现多进程,复杂的要定义一个类继承Process,每次实例化这个类的时候就等同于实例化一个进程对象 

(解决上一个程序中两个子进程重复代码的问题) 

from multiprocessing import Processimport time,os#继承Process类class SubProcess(Process):    def __init__(self,interval,name=""): #子类SubProcess的构造方法        Process.__init__(self) #Process.__init__(self) #继承父类的构造方法        self.interval = interval        self.name = name         #重写父类方法    def run(self):        print("子进程(%s)开始执行,父进程为(%s)" % (os.getpid(), os.getpid()))  # os.getpid()为获取进程号        t_stat = time.time()  # 计时开始        time.sleep(self.interval)  # 程序将被挂起n秒        t_end = time.time()  # 计时结束        print("子进程(%s)的执行时间为'%0.2f'秒" % (os.getpid(), t_end - t_stat))if __name__ == '__main__':    print("-----父进程开始执行-------")    print("父进程启动时,父进程PID为:(%s)"%(os.getpid()))  #打印父进程启动时父进程的PID    p1 = SubProcess(interval=1,name='ZARD1') #实例化子进程1    p2 = SubProcess(interval=2,name=('ZARD2')) #实例化子进程2    p1.start() #启动子进程1    p2.start() #启动子进程2    #此时父进程仍然在执行    print("pi.is_alive=%s"%(p1.is_alive()))  #p1.is_alive() 判断子进程p1是否还在执行,执行则返回ture    print("p2_is_alive=%s"%(p2.is_alive()))    #输出此时进程执行过程中的PID(进程号)    print("p1.name = %s"%(p1.name))    print("执行过程中的p1的进程号p1.pid=%s"%(p1.pid))    print("p2.name = %s" % (p2.name))    print("执行过程中的p2的进程号p2.pid=%s" % (p2.pid))    print("---等待子进程结束----")    p1.join() #等待子程序p1结束    p2.join()    print("父进程结束,此时父进程的进程号为:(%s)"%(os.getpid()))from multiprocessing import Process
import time,os
 
#继承Process类
class SubProcess(Process):
    def __init__(self,interval,name=""): #子类SubProcess的构造方法
        Process.__init__(self) #Process.__init__(self) #继承父类的构造方法
        self.interval = interval
        self.name = name
     
    #重写父类方法
    def run(self):
        print("子进程(%s)开始执行,父进程为(%s)" % (os.getpid(), os.getpid()))  # os.getpid()为获取进程号
        t_stat = time.time()  # 计时开始
        time.sleep(self.interval)  # 程序将被挂起n秒
        t_end = time.time()  # 计时结束
        print("子进程(%s)的执行时间为'%0.2f'秒" % (os.getpid(), t_end - t_stat))
 
if __name__ == '__main__':
    print("-----父进程开始执行-------")
    print("父进程启动时,父进程PID为:(%s)"%(os.getpid()))  #打印父进程启动时父进程的PID
    p1 = SubProcess(interval=1,name='ZARD1') #实例化子进程1
    p2 = SubProcess(interval=2,name=('ZARD2')) #实例化子进程2
    p1.start() #启动子进程1
    p2.start() #启动子进程2
    #此时父进程仍然在执行
    print("pi.is_alive=%s"%(p1.is_alive()))  #p1.is_alive() 判断子进程p1是否还在执行,执行则返回ture
    print("p2_is_alive=%s"%(p2.is_alive()))
    #输出此时进程执行过程中的PID(进程号)
    print("p1.name = %s"%(p1.name))
    print("执行过程中的p1的进程号p1.pid=%s"%(p1.pid))
    print("p2.name = %s" % (p2.name))
    print("执行过程中的p2的进程号p2.pid=%s" % (p2.pid))
    print("---等待子进程结束----")
    p1.join() #等待子程序p1结束
    p2.join()
    print("父进程结束,此时父进程的进程号为:(%s)"%(os.getpid()))

代码分析: 

1.4 Pool进程池

(解决当要创造成百上千个进程的情况)  

例子: 有三个水槽 ,要接10桶水,我们最多只能同时接3盆,第10盆随便找一个盆,其他两个闲置。

from multiprocessing import Pool #导入进程池
import os,time
 
def task(name):
    print("子进程(%s)执行task %s..."%(os.getpid(),name))
    time.sleep(2) #休眠2秒
 
if __name__ == '__main__':
    print("---父进程(%s)启动---"%(os.getpid()))
    p = Pool(3)  #定义一个进程池,一次最多容纳三个进程,即一次最多可同时执行三个子进程
    for i in range(10):
        p.apply_async(task,args=(i,)) #使用非阻塞的方式调用task
    print("---等待所有子进程结束---")
    p.close() #关闭进程池,关闭后进程池不再接收新的请求
    p.join() #等待子进程结束
    print("全部子进程结束")

小结:定义一个进程池,并规定一个池子中可以同时执行多少个进程,可以实现多个进程分批次的执行。 

注意:

(1)区分使用Process模块与使用进程池模块Pool的区别 

(2)对于实例对象 p,p.start()表示开始执行进程;p.join()表示结束进程

(3)注意加强阻塞与非阻塞知识点的学习

2. 验证进程是否能共享信息

引例: 

from multiprocessing import Process
 
#子进程1
def plus():
    print("---子进程1开始执行---")
    global g_num #声明全局变量
    g_num += 50
    print("在子进程1下:g_num = %d"%(g_num))
    print("---子进程1结束运行---")
 
#子进程2
def minus():
    print("---子进程2开始执行---")
    global g_num #声明全局变量
    g_num -= 50
    print("在子进程2下:g_num = %d"%(g_num))
    print("---子进程2结束运行---")
 
g_num = 100 #赋值全局变量
if __name__ == '__main__':
    print("---主进程启动---")
    print("在主进程运行中,g_num = %d"%(g_num))
    child1 = Process(target=plus) #实例化子进程1
    child2 = Process(target=minus)  # 实例化子进程2
    child1.start() #启动子进程1
    child2.start()
 
    child1.join() #等待子进程结束
    child2.join()
    print("---主进程结束---")

由以上例子可见,对于进程1,2而言,全局变量g_num并不互相影响。即有如下关系:

那么就有如下问题了,思考:如何才能实现进程之间的通讯?

答:通过 multiprocessing Queue(队列), Pipes(管道), 接下来主要演示 Queue(队列)模块。

2.1 Queue(队列)模块:

2.1.1 队列简介:

1.新来的排队的在队尾

2.最前面的完成离队后,后面一个跟上

多进程队列的使用Queue, 本身他就是一个消息队列程序 :

实践: 当Queue(3)时:

from multiprocessing import Queue #导入队列模块
if __name__ == '__main__':
    q = Queue(3) #初始化一个Queue对象,最多只能接受3条put信息
    #消息写入队列
    q.put("消息1") #将此消息1写入队列
    q.put("消息2")
    print(q.full()) #q.full() 是验证队列是否已满  没满则返回False
    q.put("消息3")  #将此消息3写入队列
    print(q.full()) #q.full() 是验证队列是否已满  满了则返回Ture
 
    #利用try看看队列已满是否还可再塞入信息
    try:
        q.put("尝试塞入第4条信息",True,1) #可能出问题的代码
    except:
        print("尝试利用q.put()向队列中继续添加信息:")
        print("队列已满,现有消息数量为:%d,无法继续添加信息。"%(q.qsize()))  #q.qsize() 返回队列中的已有信息数量
 
    try:
        q.put_nowait("尝试塞入第4条信息")  # 可能出问题的代码
    except:
        print("尝试利用q.put_nowait()向队列中继续添加信息:")
        print("队列已满,现有消息数量为:%d,无法继续添加信息。" % (q.qsize()))  # q.qsize() 返回队列中的已有信息数量
 
    #获取(打印)队列中的信息
    if not q.empty():
        print("---从队列中读取信息---")
        for i in range(q.qsize()):  #循环打印队列信息
            print(q.get_nowait())  #q.get_nowait() 读取队列信息
 
 
 

解决:

 

当Queue(4)时,打印的结果如下,可见此时可继续向队列中塞入第4条信息。

小结:

multiprocessing.Process 可以创建多进程,使用multiprocessing Queue可以实现队列操作。

2.2 实现进程间的通信

from multiprocessing import Process,Queue
import time
 
#子进程1:向队列中写入数据
def write_date(q):
    if not q.full(): #若队列没满,则写入数据
        for i in range(5):
            date = "数据" + str(i)
            q.put(date) #向队列中写入数据
            print("已写入:%s" % date)
#子进程2:向队列中读取数据
def read_date(q):
    time.sleep(1)  # 休眠1s
    while not q.empty():
        print("读取:%s" % q.get(True, 2))  # 等待2s,如果还没读取到消息,抛出异常
 
#主程序
if __name__ == '__main__':
    print("---主程序启动---")
    q = Queue()  # 父进程创建Queue,并传给各个子进程
    write_child = Process(target=write_date,args=(q,)) # 实例化进程对象,其中args=(q,)表示把队列传给子进程1
    read_child = Process(target=read_date,args=(q,))
    write_child.start()  # 启动子进程1,写入
    read_child.start()  # 启动子进程2,读取
    write_child.join()  # 等待子进程1结束
    read_child.join()  # 等待子进程2结束
    print('-----父进程结束-----')
 

小结:

(1)进程之间可以通过队列来实现通信,但需要注意的是,队列中的信息遵循“先进先出”的原则。如上数据那样,先写入数据0,则最先读出的数据也是数据0;

(2)如:

 在父进程中创建队列,再利用Process模块实例化子进程对象,target参数为子进程的函数名,args参数即为队列。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: python网络编程之进程详解

本文链接: https://www.lsjlt.com/news/161981.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python网络编程之进程详解
    目录1.进程1.1进程:1.2在python中创建进程1.3 使用multiprocessing创建进程1.3.1 单个进程时: 1.3.2 多个子进程时:1.3.3 自定...
    99+
    2022-11-12
  • python之Socket网络编程详解
    什么是网络? 网络是由节点和连线构成,表示诸多对象及其相互联系。在数学上,网络是一种图,一般认为专指加权图。网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类型的实际问题中抽象出来的模型。在计算机...
    99+
    2022-06-04
    详解 网络编程 python
  • Python进阶之网络编程
    网络通信 使用网络的目的 把多方链接在一起,进行数据传递; 网络编程就是,让不同电脑上的软件进行数据传递,即进程间通信; ip地址 ip地址概念和作用 IP地址是什么:比如192.168.1.1 这样的一些数字; ip地址的作用:用来在电...
    99+
    2023-01-31
    进阶 网络编程 Python
  • Python网络编程详解
    1、服务器就是一系列硬件或软件,为一个或多个客户端(服务的用户)提供所需的“服务”。它存在唯一目的就是等待客户端的请求,并响应它们(提供服务),然后等待更多请求。 2、客户端/服务器架构既可以应用于计算机...
    99+
    2022-06-04
    详解 网络编程 Python
  • 详解python网络进程
    目录一、多任务编程二、进程三、os.fork创建进程3.1、进程ID和退出函数四、孤儿和僵尸4.1、孤儿进程4.2、僵尸进程4.3、如何避免僵尸进程的产生五、Multiprocessing创建进程5.1、multip...
    99+
    2022-06-02
    python 网络进程
  • 详解Python Socket网络编程
    Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页、QQ 聊天、...
    99+
    2022-06-04
    详解 网络编程 Python
  • Java网络编程之UDP网络通信详解
    目录1.UDP网络通信编程原理1.1 UDP网络通信编程介绍1.2 UDP网络通信编程的基本流程2.UDP网络通信编程案例1.UDP网络通信编程原理 1.1 UDP网络通信编程介绍 ...
    99+
    2022-11-13
  • Python网络编程之协程
    What is the association与子例程一样,协程也是一种程序组件。 相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。 协程源自Simula和Modula-2语言,但也有其他语言支持。 协程更适合于用来实...
    99+
    2023-01-31
    网络编程 Python
  • python网络编程之socketser
    防伪码:存在的,忘却了,红尘万丈,入眸幻灭  在进行网络编程前我们先来说说在网络中服务器与客户端是如何交互的,也就是传说中的TCP三次握手。  三次握手的目的是为了确认客户端与服务端都能接收到对方的信息,以下是三次握手的详细过程:    第...
    99+
    2023-01-31
    网络编程 python socketser
  • 详解python的网络编程基础
    目录一.什么是网络编程二.socket1.socket的基本语法2.与socket有关的一些函数服务端函数客户端函数公共函数三.程序需求服务端分析客户端分析四.代码升级加上通信循环&...
    99+
    2022-11-12
  • python编程之网络基础
    1 套接字是一种具有通讯端点概念的计算机网络数据结构,网络化的应用程序在开始任何通讯之前都必须要建立套接字。 套接字起源于20世纪70年代,有时人们把套接字成为“伯克利套接字”或“BSD套接字”,期初,套接字被设计用在同一台主机上多个应用...
    99+
    2023-01-31
    基础 网络 python
  • 详解Java网络编程
    目录一、网络编程1.1、概述1.2、计算机网络基础1.3、网络通信要素概述1.4、IP地址和端口号(组合就是网络套接字)1.5、网络协议1.6、三次握手与四次挥手二、TCP网络编程2...
    99+
    2022-11-12
  • Java 网络编程socket编程等详解
    网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。java.net包中J2SE的API包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。java.net包中...
    99+
    2023-05-31
    java 网络编程 socket编程
  • Python网络编程之xmlrpc模块
    简介 rpc:远程过程调用协议。简单的来说就是客户端可以很方便得远程调用服务端的接口程序,而不用管底层是如何实现的。 XML-RPC的全称是XML Remote Procedure ...
    99+
    2022-11-11
  • Python网络编程之ftplib模块
    Python中默认安装的ftplib模块定义了FTP类,可用来实现简单的ftp客户端,用于上传或下载文件。 ftp登陆连接 from ftplib import FTP # 加载f...
    99+
    2022-11-11
  • Python网络编程之socket与socketserver
    目录一、基于TCP协议的socket套接字编程1、套接字工作流程1、 服务端套接字函数2、 客户端套接字函数3、 公共用途的套接字函数4、 面向锁的套接字方法5、 面向文件的套接字的...
    99+
    2022-11-11
  • C#网络编程之Socket编程
    目录一:什么是SOCKET套接字分类二:SOCKET相关概念1、端口2、协议2.1 TCP:2.2 UDP三:socket一般应用模式:四:SOCKET通信基本流程图:服务器端:客户...
    99+
    2022-11-13
  • python 网络编程详解及简单实例
    python 网络编程详解 网络编程的专利权应该属于Unix,各个平台(如windows、Linux等)、各门语言(C、C++、Python、Java等)所实现的符合自身特性的语法都大同小异。在我看来,懂得...
    99+
    2022-06-04
    详解 网络编程 实例
  • Python线程编程之Thread详解
    目录一、线程编程(Thread)1、线程基本概念1.1、什么事线程1.2、线程特征二、threading模块创建线程1、创建线程对象2、 启动线程3、 回收线程4、代码演示5、线程对...
    99+
    2022-11-12
  • Python全栈开发之网络编程
    No.1 TCP/IP 早期的计算机网络,都是由厂商规定自己的通信协议,互不兼容,为了把全世界不同类型的计算机连接起来,就必须规定一套全球通用的协议,所以就出现了TCP/IP No.2 Socket简介 要解决怎么标识一个进制,在一台电...
    99+
    2023-01-31
    网络编程 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作