Python网络编程(子进程的创建与处理、简单群聊工具)

简介:

前言:
昨天我们已经了解了多进程的原理以及它的实际使用

Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,

但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。

子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,

父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。

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

既然是进程那么就会有运行和退出
接下来我们就来了解一下进程的退出以及处理
 
孤儿进程:
    当 父进程于子进程 退出,此时 子进程就会 成为孤儿进程
    特征:
          孤儿进程会被系统指定进程收养,即 系统进程成为
这个孤儿进程 新的父进程,系统进程 会自动处理进程 退出状态

僵尸进程:
    当 子进程于父进程 退出父进程没处理子进程的 退出状态
    此时子进程 就会成为僵尸进程
    僵尸进程会滞留部分 PCB信息 在内存中,大量的僵尸进程 会消耗系统给的 内存资源
    所以要 尽量避免僵尸进程的产生

如何避免僵尸进程的产生:
    1. 父进程先退出
    2.父进程 处理子进程状态

    PID,status = os.wait
      功能:
         在父进程中 阻塞等待处理 子进程的退出
      返回值:
            pid :退出的那个 子进程PID
   status :子进程的 退出状态
      获取原来的退出状态:
             wait(status)
      pid,status = os.waitpid(pid,option)
          功能:在父进程阻塞 等待处理子进程的退出
          参数 :
                    pid    -1 表示等待任意子进程退出 
                            >0 表示等待对应PID号的子进程退出 option 
                               0 表示阻塞等待 WNOHANG 表示非阻塞 
          返回值:pid 
                        退出的那个 子进程的PID号 status 子进程的退出状态


创建二级子进程
  • 父进程创建子进程等待进程退出
  • 子进程创建下一个进程,然后立即退出
  • 二级子进程成为孤儿进程  处理具体工作


multiprocessing  模块创建进程
  1.需要 将要做的事情封装 为函数
  2.使用multiprocessing提供的 process 创建进程对象
  3.通过进程对象和process初始化进程进行 进程的设置绑定函数
  4. 启动进程,会 自动执行绑定的函数
  5 .完成进程的回收

创建进程对象:
   process()
     功能:
       创建进程对象
      参数:
        target函数对象
        name 进程称()
        args元组 用来给target 函数位置传参
        kwargs字典 用来给target 函数键值传参
   p.start()
     功能:
        启动进程自动运行terget 绑定函数,
       此时 进程被创建
   p.join([timeout])
     功能:
       等待阻塞子进程退出
     参数:超时检测
     如果 不使用join回收可能产生僵尸进程

  • 使用multiprocessing创建进程子进程同样复制父进程的全部内存空间
  • 之后自己的独立空间 执行互不干扰 子进程也有自己的PID特有资源等
  • 使用multiprocessing创建子进程,一般父进程功能就是创建子进程
  • 回收子进程返回事件交给子进程完成






简单群聊:

功能:
  类似QQ群聊
  1.进入聊天室需要输入姓名 姓名不能重复
  2.有人进入聊天室会向其他人发起通知  xxx进入聊天室
  3.如果一个人发消息则其他人都能收到  xxx说:...
  4.如果某个人退出聊天室也会收到通知  xxx退出聊天室
  5.服务端可以喊话:此时群里所有的都能收到服务端消息  管理员说:...


服务器端:

from socket import * 
import os, sys


# 发送管理员消息
def do_child(s, addr):
    while True:
        msg = input("管理员消息:")
        msg = "C 管理员 " + msg
        s.sendto(msg.encode(), addr)


# 用户登录
def do_login(s, user, name, addr):
    if (name in user) or name == "管理员":
        s.sendto("该用户已存在".encode(), addr)
        return
    s.sendto(b'OK', addr)
    # 通知所有人
    msg = "\n欢迎 %s 进入聊天室" % name
    for i in user:
        s.sendto(msg.encode(), user[i])
    # 插入user
    user[name] = addr


def do_chat(s, user, name, data):
    msg = "\n{} 说: {}".format(name, data)
    for i in user:
        if i != name:
            s.sendto(msg.encode(), user[i])


def do_quit(s, user, name):
    msg = "\n%s 离开了聊天室" % name
    for i in user:
        if i == name:
            s.sendto(b'EXIT', user[i])
        else:
            s.sendto(msg.encode(), user[i])
    del user[name]  # 删除离开的用户


# 接收客户端请求并处理
def do_parent(s):
    # 用于存储用户 {'Alex':('127.0.0.1',8888)}
    user = {}
    while True:
        msg, addr = s.recvfrom(1024)
        msgList = msg.decode().split(' ')
        if msgList[0] == 'L':
            do_login(s, user, msgList[1], addr)
        elif msgList[0] == 'C':
            # "C Levi [I miss you]"
            data = ' '.join(msgList[2:])
            do_chat(s, user, msgList[1], data)
        elif msgList[0] == 'Q':
            do_quit(s, user, msgList[1])


# 创建套接字,网络连接,创建父子进程
def main():
    # server address
    ADDR = ('0.0.0.0', 8888)
    # 创建套接字
    s = socket(AF_INET, SOCK_DGRAM)
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    s.bind(ADDR)

    # 创建父子进程
    pid = os.fork()
    if pid < 0:
        sys.exit("创建进程失败")
    elif pid == 0:
        do_child(s, ADDR)
    else:
        do_parent(s)

if __name__ == "__main__":
    main()


客户端:

from socket import * 
import sys, os


def login(s, ADDR):
    while True:
        name = input("请输入用户名:")
        msg = "L " + name
        s.sendto(msg.encode(), ADDR)
        # 接收登录结果
        data, addr = s.recvfrom(1024)
        if data.decode() == 'OK':
            print("@进入聊天室@")
            return name
        else:
            print(data.decode())


# 发送消息
def do_child(s, name, addr):
    while True:
        text = input("发言(quit退出):")
        # 退出
        if text.strip() == "quit":
            msg = "Q " + name
            s.sendto(msg.encode(), addr)
            sys.exit("退出聊天室")

        msg = "C %s %s" % (name, text)
        s.sendto(msg.encode(), addr)


# 接收消息
def do_parent(s):
    while True:
        msg, addr = s.recvfrom(1024)
        if msg.decode() == 'EXIT':
            sys.exit(0)
        print(msg.decode() + "\n发言(quit退出):",end="")


# main控制套接字的创建
def main():
    if len(sys.argv) < 3:
        print("argv is error")
        return
    HOST = sys.argv[1]
    PORT = int(sys.argv[2])
    ADDR = (HOST, PORT)

    s = socket(AF_INET, SOCK_DGRAM)

    name = login(s, ADDR)
    if name:
        pid = os.fork()
        if pid < 0:
            sys.exit("创建子进程失败")
        elif pid == 0:
            do_child(s, name, ADDR)
        else:
            do_parent(s)
    else:
        return


if __name__ == "__main__":
    main()



    


相关文章
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
眼疾识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了4种常见的眼疾图像数据集(白内障、糖尿病性视网膜病变、青光眼和正常眼睛) 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,实现用户上传一张眼疾图片识别其名称。
103 5
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
|
2月前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
318 55
|
20天前
|
测试技术 数据库 Python
Python装饰器实战:打造高效性能计时工具
在数据分析中,处理大规模数据时,分析代码性能至关重要。本文介绍如何使用Python装饰器实现性能计时工具,在不改变现有代码的基础上,方便快速地测试函数执行时间。该方法具有侵入性小、复用性强、灵活度高等优点,有助于快速发现性能瓶颈并优化代码。通过设置循环次数参数,可以更准确地评估函数的平均执行时间,提升开发效率。
96 61
Python装饰器实战:打造高效性能计时工具
|
25天前
|
数据可视化 算法 数据挖掘
Python时间序列分析工具Aeon使用指南
**Aeon** 是一个遵循 scikit-learn API 风格的开源 Python 库,专注于时间序列处理。它提供了分类、回归、聚类、预测建模和数据预处理等功能模块,支持多种算法和自定义距离度量。Aeon 活跃开发并持续更新至2024年,与 pandas 1.4.0 版本兼容,内置可视化工具,适合数据探索和基础分析任务。尽管在高级功能和性能优化方面有提升空间,但其简洁的 API 和完整的基础功能使其成为时间序列分析的有效工具。
68 37
Python时间序列分析工具Aeon使用指南
|
13天前
|
安全 Linux 网络安全
利用Python脚本自动备份网络设备配置
通过本文的介绍,我们了解了如何利用Python脚本自动备份网络设备配置。该脚本使用 `paramiko`库通过SSH连接到设备,获取并保存配置文件。通过定时任务调度,可以实现定期自动备份,确保网络设备配置的安全和可用。希望这些内容能够帮助你在实际工作中实现网络设备的自动化备份。
39 14
|
2月前
|
机器学习/深度学习 人工智能 算法
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
214 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
|
1月前
|
存储 算法 Serverless
剖析文件共享工具背后的Python哈希表算法奥秘
在数字化时代,文件共享工具不可或缺。哈希表算法通过将文件名或哈希值映射到存储位置,实现快速检索与高效管理。Python中的哈希表可用于创建简易文件索引,支持快速插入和查找文件路径。哈希表不仅提升了文件定位速度,还优化了存储管理和多节点数据一致性,确保文件共享工具高效运行,满足多用户并发需求,推动文件共享领域向更高效、便捷的方向发展。
|
2月前
|
算法 网络协议 Python
探秘Win11共享文件夹之Python网络通信算法实现
本文探讨了Win11共享文件夹背后的网络通信算法,重点介绍基于TCP的文件传输机制,并提供Python代码示例。Win11共享文件夹利用SMB协议实现局域网内的文件共享,通过TCP协议确保文件传输的完整性和可靠性。服务器端监听客户端连接请求,接收文件请求并分块发送文件内容;客户端则连接服务器、接收数据并保存为本地文件。文中通过Python代码详细展示了这一过程,帮助读者理解并优化文件共享系统。
|
2月前
|
数据可视化 编译器 Python
Manim:数学可视化的强大工具 | python小知识
Manim(Manim Community Edition)是由3Blue1Brown的Grant Sanderson开发的数学动画引擎,专为数学和科学可视化设计。它结合了Python的灵活性与LaTeX的精确性,支持多领域的内容展示,能生成清晰、精确的数学动画,广泛应用于教育视频制作。安装简单,入门容易,适合教育工作者和编程爱好者使用。
483 7
|
2月前
|
机器学习/深度学习 人工智能 算法
深度学习入门:用Python构建你的第一个神经网络
在人工智能的海洋中,深度学习是那艘能够带你远航的船。本文将作为你的航标,引导你搭建第一个神经网络模型,让你领略深度学习的魅力。通过简单直观的语言和实例,我们将一起探索隐藏在数据背后的模式,体验从零开始创造智能系统的快感。准备好了吗?让我们启航吧!
99 3

热门文章

最新文章