[记录]Python的master-worker和epoll模式
- #master-worker模型:
- #coding:utf-8
- import os
- import sys
- import socket
- import time
- import traceback
- import errno
- import signal
- class Worker(object):
- def __init__(self, sock):
- self.sock = sock
- def accept(self):
- client, addr = self.sock.accept()
- client.setblocking(True)
- self.handle(client, addr)
- def init_process(self):
- self.sock.setblocking(False)
- while True:
- try:
- time.sleep(1)
- self.accept()
- continue
- except Exception as e:
- msg = traceback.format_exc()
- with open("sub_"+str(os.getpid())+".txt","a") as f:
- f.write(msg+"\n")
- if hasattr(e, "errno"):
- if e.errno not in (errno.EAGAIN, errno.ECONNABORTED, errno.EWOULDBLOCK):
- msg = traceback.format_exc()
- else:
- raise
- def handle(self, client, addr):
- data = client.recv(1024)
- pid = os.getpid()
- data += str(pid)
- # print("receive:{} pid:{}".format(data, pid))
- client.send("back:"+data)
- client.close()
- class Server(object):
- def __init__(self):
- self.port = ("127.0.0.1", 8004)
- self.sock = socket.socket()
- self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- self.sock.bind(self.port)
- self.sock.setblocking(False)
- self.sock.listen(5)
- self.WORKERS = {}
- def run(self):
- self.init_signals()
- for i in range(2):
- self.spawn_worker()
- print(i)
- # self.spawn_worker()
- for k in self.WORKERS:
- print(k, self.WORKERS[k])
- while True:
- import time
- time.sleep(3)
- try:
- pid, status = os.waitpid(-1, os.WNOHANG)
- print("kill pid: {}, status: {}".format(pid, status))
- except os.error:
- print("error")
- def init_signals(self):
- signal.signal(signal.SIGTTIN, self.incr_one)
- signal.signal(signal.SIGTTOU, self.decr_one)
- def incr_one(self, signo, frame):
- self.spawn_worker()
- for k in self.WORKERS:
- print(k, self.WORKERS[k])
- def decr_one(self, signo, frame):
- for k in self.WORKERS:
- os.kill(k, signal.SIGKILL)
- break
- def spawn_worker(self):
- worker = Worker(self.sock)
- pid = os.fork()
- if pid != 0:
- worker.pid = pid
- self.WORKERS[pid] = worker
- return pid
- worker.pid = os.getpid()
- worker.init_process()
- sys.exit(0)
- if __name__ == "__main__":
- server = Server()
- server.run()
- =======================================================================
- epoll模型:
- server:
- #-*- coding:utf8 -*-
- import socket
- import select
- import os
- address = "0.0.0.0"
- port = 10001
- sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- def main():
- global address,port,sock
- epoll = select.epoll()
- #获取创建好的sock的文件描述符
- fd = sock.fileno()
- sock.bind((address,port))
- sock_dict = {}
- sock_dict[fd] = sock
- #对该sock进行注册
- epoll.register(fd,select.EPOLLIN)
- sock.listen(5)
- while True:
- events = epoll.poll(1)
- for fileno,event in events:
- #获取到的文件描述符和sock的相同就说明是一个新的连接
- if fileno == fd:
- (client,address) = sock.accept()
- print address
- client.setblocking(0)
- #将新的连接进行注册,用来接收消息
- epoll.register(client.fileno(),select.EPOLLIN)
- sock_dict[client.fileno()] = client
- elif event & select.EPOLLIN:
- print "fileno:",fileno
- data = sock_dict[fileno].recv(128)
- if data == '你好':
- print "Data:",data.decode('UTF-8')
- sock_dict[fileno].send("你好")
- elif len(data) == 0:
- print "线路%d已下线"%fileno
- epoll.unregister(fileno)
- else:
- print "Data:",data
- if __name__ == '__main__':
- main()
- client:
- #coding: UTF-8
- import socket
- import select
- address = "127.0.0.1"
- port = 10001
- sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- def main():
- global address,port,sock
- sock.connect((address,port))
- epoll = select.epoll()
- fd = sock.fileno()
- #这里的epoll注册只是用来异步接收服务端发过来的消息
- epoll.register(fd,select.EPOLLIN)
- while True:
- events = epoll.poll(1)
- for fileno,event in events:
- if fileno == fd:
- if event & select.EPOLLIN:
- data = sock.recv(128)
- print data
- data = raw_input(">")
- if data == 'q':
- break
- elif data == '':
- print "不能发送空消息"
- continue
- sock.send(data)
- sock.close()
- main()
[记录]Python的master-worker和epoll模式的更多相关文章
- 记录Python学习中的几个小问题
记录Python学习中的几个小问题,和C#\JAVA的习惯都不太一样. 1.Django模板中比较两个值是否相等 错误的做法 <option value="{{group.id}}&q ...
- Python进阶:设计模式之迭代器模式
在软件开发领域中,人们经常会用到这一个概念——“设计模式”(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一本圣经级的书籍<设计模式:可复用面向对象软件的基础 ...
- python celery多worker、多队列、定时任务
python celery多worker.多队列.定时任务
- python中文件操作的六种模式及对文件某一行进行修改的方法
一.python中文件操作的六种模式分为:r,w,a,r+,w+,a+ r叫做只读模式,只可以读取,不可以写入 w叫做写入模式,只可以写入,不可以读取 a叫做追加写入模式,只可以在末尾追加内容,不可以 ...
- python打开文件可以有多种模式
一.python打开文件可以有多种模式,读模式.写模式.追加模式,同时读写的模式等等,这里主要介绍同时进行读写的模式r+ python通过open方法打开文件 file_handler = open( ...
- 应对百万访问量的epoll模式
写在前面 select/poll与epoll select/poll模型工作机理 select/poll模型的局限 epoll模型工作机理 epoll的局限 golang中的epoll golang源 ...
- python设计模式之模型-视图-控制器模式
python设计模式之模型-视图-控制器模式 关注点分离( Separation of Concerns, SoC)原则是软件工程相关的设计原则之一. SoC原则背后的思想是将一个应用切分成不同的部分 ...
- 使用配置文件方式记录Python程序日志
开发者可以通过三种方式配置日志记录: 调用配置方法的Python代码显式创建记录器.处理程序和格式化程序. 创建日志配置文件并使用fileConfig() 函数读取. 创建配置信息字典并将其传递给di ...
- Beats:使用 Elastic Stack 记录 Python 应用日志
文章转载自:https://elasticstack.blog.csdn.net/article/details/112259500 日志记录实际上是每个应用程序都必须具备的功能.无论你选择基于哪种技 ...
随机推荐
- JavaScript关于原型的相关内容
function Person () { } Person.prototype.name = 'Alan'; Person.prototype.age = 26; Person.prototype.j ...
- Win10的UWP之标题栏的返回键(一)
原文:Win10的UWP之标题栏的返回键(一) 关于返回键,放在标题栏是目前较为完美的一种方案.继前一篇的Hello World,博主进行一些修改实现该方法. - - - - - - - - - - ...
- Qt使用第三方库3rdparty
简述 在 Qt 中经常会用到第三方库,例如:FFmpeg.OpenCV 等.第三方库的使用比较简单,只需要一些基本的配置就可以搞定,一起来看看吧! 简述 第三方库 源代码 库文件 目标目录 第三方库 ...
- Delphi 7下IGDIPlus库的使用
IGDI+是一个免费开源封装微软GDI+功能的Delphi库,该库使得可以用Delphi语言代码快速简短的实现复杂GDI+应用程序.官方网站:http://www.mitov.com/html/igd ...
- Java Socket基础[备忘]
1.服务端----Server.java import javax.swing.*; import java.io.*; import java.net.*; import java.awt.*; i ...
- Codility------CyclicRotation
Task description A zero-indexed array A consisting of N integers is given. Rotation of the array mea ...
- git初学【常用命令、上传项目到码云或从码云拉取、克隆项目】
1.下载git.https://git-scm.com/ 注册码云:https://gitee.com/2.安装git: 默认安装即可: 安装完成之后打开git bash进行最后一步配置 输 ...
- springboot部署到tomcat
把spring-boot项目按照平常的web项目一样发布到tomcat容器下 多点经验: 1.保证运行环境的jdk和开发环境一致,不然class文件无法被编译 2.保证tomcat和java的版本匹配 ...
- Hyperledger Fabric1.4环境搭建过程
简单记录一下fabric版本1.4的环境搭建,运行环境为Ubuntu18.04,其中一些内容是根据官方文档整理的,如有错误欢迎批评指正. 本文只介绍最简单的环境搭建方法,具体的环境搭建解析在这里深入解 ...
- Java NIO 学习笔记(二)----聚集和分散,通道到通道
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...