#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模式的更多相关文章

  1. 记录Python学习中的几个小问题

    记录Python学习中的几个小问题,和C#\JAVA的习惯都不太一样. 1.Django模板中比较两个值是否相等 错误的做法 <option value="{{group.id}}&q ...

  2. Python进阶:设计模式之迭代器模式

    在软件开发领域中,人们经常会用到这一个概念——“设计模式”(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一本圣经级的书籍<设计模式:可复用面向对象软件的基础 ...

  3. python celery多worker、多队列、定时任务

    python celery多worker.多队列.定时任务  

  4. python中文件操作的六种模式及对文件某一行进行修改的方法

    一.python中文件操作的六种模式分为:r,w,a,r+,w+,a+ r叫做只读模式,只可以读取,不可以写入 w叫做写入模式,只可以写入,不可以读取 a叫做追加写入模式,只可以在末尾追加内容,不可以 ...

  5. python打开文件可以有多种模式

    一.python打开文件可以有多种模式,读模式.写模式.追加模式,同时读写的模式等等,这里主要介绍同时进行读写的模式r+ python通过open方法打开文件 file_handler = open( ...

  6. 应对百万访问量的epoll模式

    写在前面 select/poll与epoll select/poll模型工作机理 select/poll模型的局限 epoll模型工作机理 epoll的局限 golang中的epoll golang源 ...

  7. python设计模式之模型-视图-控制器模式

    python设计模式之模型-视图-控制器模式 关注点分离( Separation of Concerns, SoC)原则是软件工程相关的设计原则之一. SoC原则背后的思想是将一个应用切分成不同的部分 ...

  8. 使用配置文件方式记录Python程序日志

    开发者可以通过三种方式配置日志记录: 调用配置方法的Python代码显式创建记录器.处理程序和格式化程序. 创建日志配置文件并使用fileConfig() 函数读取. 创建配置信息字典并将其传递给di ...

  9. Beats:使用 Elastic Stack 记录 Python 应用日志

    文章转载自:https://elasticstack.blog.csdn.net/article/details/112259500 日志记录实际上是每个应用程序都必须具备的功能.无论你选择基于哪种技 ...

随机推荐

  1. c#利用IronPython调用python的过程种种问题

    c#利用IronPython调用python的过程种种问题 小菜鸟一枚,最新学习了Python,感觉语言各种简短,各种第三方类库爽歪歪,毕竟之前是从c#转来的,看到Python的request类各种爽 ...

  2. Failed to recover corrupt cache entry

    RangeError java.lang.RuntimeException: ERROR: Failed to recover corrupt cache entry at com.sun.deplo ...

  3. Cannot read property 'substring' of undefined

    这个是在使用 jquery的ztree插件过程中遇到的错误 原因是数据的格式和规定的格式不一致,需要把数据按照模板给的样子来

  4. Linux下C/C++帮助手册安装方法

    1.  安装C的帮助手册 如果你使用的Linux发行版, 默认没有安装C语言的库函数MAN手册, 使用下面的方法解决: # sudo apt-get install manpages # sudo a ...

  5. C语言的setlocale和localtime函数(C++也可用)

    Example 1234567891011121314151617181920212223242526272829303132 /* setlocale example */ #include < ...

  6. QImage的浅拷贝与深拷贝

     首先简单说说什么是浅拷贝和深拷贝:浅拷贝就比如像引用类型,而深拷贝就比如值类型,即浅拷贝是共用一块内存的,而深拷贝是复制一份内容.   我们再来看看QImage类的几个构造函数: // 浅拷贝 QI ...

  7. 第四章 自定义sol合约转化java代码,并实现调用

     鉴于笔者以前各大博客教程都有很多人提问,早期建立一个技术交流群,里面技术体系可能比较杂,想了解相关区块链开发,技术提问,请加QQ群:538327407 准备工作 1.官方参考说明文档 https:/ ...

  8. 使用 python 提取照片中的手机信息

    使用 python 提取照片中的手机信息 最近在做一个项目,有一个很重要的点是需要获取使用用户的手机信息,这里我选择从照片中获取信息.有人会问为什么不从手机里面直接获取设备信息.由于现在android ...

  9. aspose授权亲测可用配套代码

    支持excel,word,ppt,pdf using Aspose.Cells; using Aspose.Words.Saving; using ESBasic; using OMCS.Engine ...

  10. Linux系统下解锁Oracle的Scott用户

    1).在Oracle用户下面输入命令:lsnrctl status查看监听是否开启,如果未开启则需要开启监听,输入命令:lsnrctl start; 2).如果没有设置监听的话需要先建立一个监听,然后 ...