1. #master-worker模型:
  2. #coding:utf-8
  3. import os
  4. import sys
  5. import socket
  6. import time
  7. import traceback
  8. import errno
  9. import signal
  10.  
  11. class Worker(object):
  12. def __init__(self, sock):
  13. self.sock = sock
  14.  
  15. def accept(self):
  16. client, addr = self.sock.accept()
  17. client.setblocking(True)
  18. self.handle(client, addr)
  19.  
  20. def init_process(self):
  21. self.sock.setblocking(False)
  22. while True:
  23. try:
  24. time.sleep(1)
  25. self.accept()
  26. continue
  27. except Exception as e:
  28. msg = traceback.format_exc()
  29. with open("sub_"+str(os.getpid())+".txt","a") as f:
  30. f.write(msg+"\n")
  31. if hasattr(e, "errno"):
  32. if e.errno not in (errno.EAGAIN, errno.ECONNABORTED, errno.EWOULDBLOCK):
  33. msg = traceback.format_exc()
  34. else:
  35. raise
  36.  
  37. def handle(self, client, addr):
  38. data = client.recv(1024)
  39. pid = os.getpid()
  40. data += str(pid)
  41. # print("receive:{} pid:{}".format(data, pid))
  42. client.send("back:"+data)
  43. client.close()
  44.  
  45. class Server(object):
  46. def __init__(self):
  47. self.port = ("127.0.0.1", 8004)
  48. self.sock = socket.socket()
  49. self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  50. self.sock.bind(self.port)
  51. self.sock.setblocking(False)
  52. self.sock.listen(5)
  53. self.WORKERS = {}
  54.  
  55. def run(self):
  56. self.init_signals()
  57. for i in range(2):
  58. self.spawn_worker()
  59. print(i)
  60. # self.spawn_worker()
  61. for k in self.WORKERS:
  62. print(k, self.WORKERS[k])
  63. while True:
  64. import time
  65. time.sleep(3)
  66. try:
  67. pid, status = os.waitpid(-1, os.WNOHANG)
  68. print("kill pid: {}, status: {}".format(pid, status))
  69. except os.error:
  70. print("error")
  71.  
  72. def init_signals(self):
  73. signal.signal(signal.SIGTTIN, self.incr_one)
  74. signal.signal(signal.SIGTTOU, self.decr_one)
  75.  
  76. def incr_one(self, signo, frame):
  77. self.spawn_worker()
  78. for k in self.WORKERS:
  79. print(k, self.WORKERS[k])
  80.  
  81. def decr_one(self, signo, frame):
  82. for k in self.WORKERS:
  83. os.kill(k, signal.SIGKILL)
  84. break
  85.  
  86. def spawn_worker(self):
  87. worker = Worker(self.sock)
  88.  
  89. pid = os.fork()
  90. if pid != 0:
  91. worker.pid = pid
  92. self.WORKERS[pid] = worker
  93. return pid
  94.  
  95. worker.pid = os.getpid()
  96. worker.init_process()
  97. sys.exit(0)
  98.  
  99. if __name__ == "__main__":
  100. server = Server()
  101. server.run()
  102.  
  103. =======================================================================
  104. epoll模型:
  105. server:
  106. #-*- coding:utf8 -*-
  107. import socket
  108. import select
  109. import os
  110.  
  111. address = "0.0.0.0"
  112. port = 10001
  113. sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  114.  
  115. def main():
  116. global address,port,sock
  117. epoll = select.epoll()
  118. #获取创建好的sock的文件描述符
  119. fd = sock.fileno()
  120. sock.bind((address,port))
  121. sock_dict = {}
  122. sock_dict[fd] = sock
  123. #对该sock进行注册
  124. epoll.register(fd,select.EPOLLIN)
  125. sock.listen(5)
  126. while True:
  127. events = epoll.poll(1)
  128. for fileno,event in events:
  129. #获取到的文件描述符和sock的相同就说明是一个新的连接
  130. if fileno == fd:
  131. (client,address) = sock.accept()
  132. print address
  133. client.setblocking(0)
  134. #将新的连接进行注册,用来接收消息
  135. epoll.register(client.fileno(),select.EPOLLIN)
  136. sock_dict[client.fileno()] = client
  137. elif event & select.EPOLLIN:
  138. print "fileno:",fileno
  139. data = sock_dict[fileno].recv(128)
  140. if data == '你好':
  141. print "Data:",data.decode('UTF-8')
  142. sock_dict[fileno].send("你好")
  143. elif len(data) == 0:
  144. print "线路%d已下线"%fileno
  145. epoll.unregister(fileno)
  146. else:
  147. print "Data:",data
  148. if __name__ == '__main__':
  149. main()
  150.  
  151. client:
  152. #coding: UTF-8
  153.  
  154. import socket
  155. import select
  156.  
  157. address = "127.0.0.1"
  158. port = 10001
  159. sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  160.  
  161. def main():
  162. global address,port,sock
  163. sock.connect((address,port))
  164. epoll = select.epoll()
  165. fd = sock.fileno()
  166. #这里的epoll注册只是用来异步接收服务端发过来的消息
  167. epoll.register(fd,select.EPOLLIN)
  168. while True:
  169. events = epoll.poll(1)
  170. for fileno,event in events:
  171. if fileno == fd:
  172. if event & select.EPOLLIN:
  173. data = sock.recv(128)
  174. print data
  175. data = raw_input(">")
  176. if data == 'q':
  177. break
  178. elif data == '':
  179. print "不能发送空消息"
  180. continue
  181. sock.send(data)
  182. sock.close()
  183. 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. JavaScript关于原型的相关内容

    function Person () { } Person.prototype.name = 'Alan'; Person.prototype.age = 26; Person.prototype.j ...

  2. Win10的UWP之标题栏的返回键(一)

    原文:Win10的UWP之标题栏的返回键(一) 关于返回键,放在标题栏是目前较为完美的一种方案.继前一篇的Hello World,博主进行一些修改实现该方法. - - - - - - - - - - ...

  3. Qt使用第三方库3rdparty

    简述 在 Qt 中经常会用到第三方库,例如:FFmpeg.OpenCV 等.第三方库的使用比较简单,只需要一些基本的配置就可以搞定,一起来看看吧! 简述 第三方库 源代码 库文件 目标目录 第三方库 ...

  4. Delphi 7下IGDIPlus库的使用

    IGDI+是一个免费开源封装微软GDI+功能的Delphi库,该库使得可以用Delphi语言代码快速简短的实现复杂GDI+应用程序.官方网站:http://www.mitov.com/html/igd ...

  5. Java Socket基础[备忘]

    1.服务端----Server.java import javax.swing.*; import java.io.*; import java.net.*; import java.awt.*; i ...

  6. Codility------CyclicRotation

    Task description A zero-indexed array A consisting of N integers is given. Rotation of the array mea ...

  7. git初学【常用命令、上传项目到码云或从码云拉取、克隆项目】

    1.下载git.https://git-scm.com/   注册码云:https://gitee.com/2.安装git:  默认安装即可:  安装完成之后打开git bash进行最后一步配置  输 ...

  8. springboot部署到tomcat

    把spring-boot项目按照平常的web项目一样发布到tomcat容器下 多点经验: 1.保证运行环境的jdk和开发环境一致,不然class文件无法被编译 2.保证tomcat和java的版本匹配 ...

  9. Hyperledger Fabric1.4环境搭建过程

    简单记录一下fabric版本1.4的环境搭建,运行环境为Ubuntu18.04,其中一些内容是根据官方文档整理的,如有错误欢迎批评指正. 本文只介绍最简单的环境搭建方法,具体的环境搭建解析在这里深入解 ...

  10. Java NIO 学习笔记(二)----聚集和分散,通道到通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...