首页 文章 精选 留言 我的

精选列表

搜索[加密工具],共10000篇文章
优秀的个人博客,低调大师

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()

优秀的个人博客,低调大师

超级简单:共享两个自动生成存储过程的工具

开发一个项目或者开发一个应用系统初期大多数都是从数据库,类,UI界面开始的。其中最令人厌烦的是写些简单的CRUD的存储过程,以及调用这些存储过程的方法的类。 我花了很多时间在网上寻找,去找一个能根据能数据库中一个存在的数据表,为我们产生大部分存储过程和调用这些存储过程C#代码的实用的程序。这里共享两个我觉得还不错的程序给大家。 第一个是SQLAutoGen,如下图: 程序地址:http://www.codeproject.com/KB/database/SQLAutoGen.aspx 这是通过迭代我们选择数据表的列,来产生我们需要的代码。通过使用选择一些不同列(将出现在where子句中),使生产脚本变得相当智能。 (见下面的示例代码示例) 看上面图片,能抵得说很多话,它来表明这个应用程序的操作。 下面是这些代码,通过程序以不同的方式迭代本身,这里一个结合了SqlClient和SqlSMO访问数据库,得到table和columns等信息: 代码 代码 下面是一个示例表画面,以及随后产生的脚本。 代码 第二个是codeplex上面的程序:Stored Procedure Generator (for SQL Server 2000/2005) ,界面如下图所示: 解决方案的结构如下: 项目地址:http://spgen.codeplex.com/ 代码不是特别的难,有兴趣可以自己下载研究。这个程序产生的存储过程中的where子句中的列是固定的,注定了没有第一个程序那么灵活。 本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/archive/2009/12/31/1636460.html,如需转载请自行联系原作者

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册