python3.x 多路IO复用补充asyncio

2019-12-12 05:09栏目:bob体育app
TAG:

asyncio模块是python之父写的模块,按说应该是可信的,python3.6本子定义为平安版本。

python多线程socket编制程序之多顾客端连着,pythonsocket

Python中得以达成socket通讯的服务端比较复杂,而客商端特别简单,所以顾客端基本上都是用sockct模块实现,而服务
端用有那些模块能够使用,如下:

图片 1

1、客户端

#!/usr/bin/env python
#coding:utf-8
'''
file:client.py
date:9/9/17 3:43 PM
author:lockey
email:[email protected]
desc:socket编程客户端,python3.6.2
'''
import socket,sys
HOST = '192.168.1.6'
PORT = 8998
ADDR =(HOST,PORT)
BUFSIZE = 1024

sock = socket.socket()
try:
 sock.connect(ADDR)
 print('have connected with server')

 while True:
  data = input('lockey# ')
  if len(data)>0:
  print('send:',data)
  sock.sendall(data.encode('utf-8')) #不要用send()
  recv_data = sock.recv(BUFSIZE)
  print('receive:',recv_data.decode('utf-8'))
  else:
  sock.close()
  break
except Exception:
 print('error')
 sock.close()
 sys.exit()

2、SocketServer模块

为了可以让四个顾客端同有难题间对接服务并开展通讯,服务端将运用SocketServer模块来贯彻,那样的话客户不用在子线程甘休后,利用父进度对它进行管理,也不用关爱socket的破产,一切都由SocketServer来成功。

#!/usr/bin/env python
#coding:utf-8
'''
file:client.py
date:9/9/17 3:43 PM
author:lockey
email:[email protected]
desc:socket编程服务器端,python3.6.2
'''
from socketserver import BaseRequestHandler,ThreadingTCPServer
import threading

BUF_SIZE=1024

class Handler(BaseRequestHandler):
 def handle(self):
  address,pid = self.client_address
  print('%s connected!'%address)
  while True:
   data = self.request.recv(BUF_SIZE)
   if len(data)>0:
    print('receive=',data.decode('utf-8'))
    cur_thread = threading.current_thread()
    #response = '{}:{}'.format(cur_thread.ident,data)
    self.request.sendall('response'.encode('utf-8'))
    print('send:','response')
   else:
    print('close')
    break

if __name__ == '__main__':
 HOST = '192.168.1.6'
 PORT = 8998
 ADDR = (HOST,PORT)
 server = ThreadingTCPServer(ADDR,Handler) #参数为监听地址和已建立连接的处理类
 print('listening')
 server.serve_forever() #监听,建立好TCP连接后,为该连接创建新的socket和线程,并由处理类中的handle方法处理
 print(server)

以下测量检验中笔者动用别的后生可畏台主机和本机的两个中断去老是服务器,都得以健康连接何况能扩充数据应答人机联作

图片 2

小心:此程序示例运转平台为rhel7.2.x86_64,python版本为3.6.2,对于windows平台和非同意气风发python版本的客商只怕相当不够一定的包容性,假使是别的平台客商请自行改过!!

以上正是本文的全体内容,希望对我们的读书抱有利于,也盼望我们多多指教帮客之家。

Python中落到实处socket通讯的服务端相比复杂,而客商端相当轻易,所以顾客端基本上都以用so...

事情发生早先大家学了不胜枚举进程间的通讯,多进程并发等等,几这段时间我们来上学线程,线程和进度是何许关联,进度和线程有啥样相通而又有啥样两样明日就来发表这几个答案。

说明书:

 

轮廓定义:该模块提供了接纳协程编写单线程并发代码,通过套接字和别的财富复用I​​ / O访谈,运营网络顾客端和服务器以致任何有关原语的底工布局。

本篇导航:

简易利用(基于wsgi的报告急察方器)

  • 线程概论
  • python的产出编制程序之八线程
  • Python GIL(Global Interpreter Lock)
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @Time    : 2018/8/21 10:40
 4 # @Author  : WangYue
 5 # @Site    : 
 6 # @File    : alertor_uwsgi.py
 7 # @Software: PyCharm
 8 
 9 #加入环境变量避免程序报错
10 import sys,os
11 sys.path.append(os.path.dirname(os.path.dirname(__file__)))
12 
13 #引入wsgi模型,这里主要是弄一个简单的http模型来说明asyncio的简单使用
14 from wsgiref.simple_server import make_server
15 
16 #引入asyncio
17 import asyncio
18 
19 #引入其他可能的依赖
20 from threading import Thread
21 import json
22 
23 #引入本程序其他的内容,与asyncio无关是程序业务的其他部分
24 from conf.alertor_conf import ALERTOR_CONFIG
25 from model.alert_method_class import SendMail
26 
27 #定义一个运行asyncio loop 的线程,去单独运行它
28 def start_loop(loop):
29     asyncio.set_event_loop(loop)
30     loop.run_forever()
31 new_loop = asyncio.new_event_loop() #这个new_loop将会用于运行异步程序
32 t = Thread(target=start_loop, args=(new_loop,))
33 t.start() #利用多线程,额外起一个线程运行asyncio loop然后它在自身使用协程之类处异步处理业务
34 
35 
36 #这是wsgi主业务程序,application是wsgi的入口程序,wsgi就规定了这么个函数名,这样写wsgi就认可它是入口了。传参也是wsgi的规定,第一个是环境,第二个是响应
37 def application(env,start_res):
38     res_headers=[('Content-type', 'text/plain')]
39     if env["REQUEST_METHOD"]=='POST':
40         # the environment variable CONTENT_LENGTH may be empty or missing
41         try:
42             if env['PATH_INFO'] != "/send_alert":
43                 status = "404 func is not in use"
44                 start_res(status, res_headers)
45                 return [b"func is not in use"]
46 
47             request_body_size = int(env.get('CONTENT_LENGTH', 0))
48             status = "200 OK"
49             request_body = env['wsgi.input'].read(request_body_size)
50             print("post_info -->", request_body.decode())
51             r_body=json.loads(request_body.decode())
52             #就这里一行代码,new_loop.call_soon_threadsafe(),告诉asyncio去运行第一个参数的函数名,后边的参数是被运行函数的传参,有多少就传参多少个,这是异步的,非阻塞的。
53             new_loop.call_soon_threadsafe(SendMail.sendEmail,"Alertor Alarm level:"+r_body["level"]+"  server: "+r_body["server"],r_body)
54             start_res(status,res_headers)
55             return [b"ok send alert......."]
56         except (ValueError):
57             status = "404 json data not found key"
58             request_body_size = 0
59             start_res(status, res_headers)
60             return [b"get post info faild"]
61 
62     else:
63         status = "403 method error"
64         start_res(status,res_headers)
65         return [b'method error']
66 
67 # 1、只接受POST请求。数据为json格式,json中标记的,包括但不限于,包括的信息将会入库,其他信息,在告警时会一并发出
68 # {
69 #     "level":"high", #告警级别,"high","medium","info",这个可以在配置文件中配置,配置信息是个列表,有序的从左至右为["high","medium","info"],对应后续告警逻辑及post中json的本字段。
70 #     "@timestamp":"",#告警时间
71 #     "server":"",#告警源,可以是ip,主机名,服务名等可标识的
72 #     "message":""#具体的告警信息
73 # }
74 # 2、根据json中的level自动选择告警途径,选择方式,在配置文件中的alert_method字典信息
75 # 3、将告警内容,存储数据库,便于日后查询
76 # 4、后续提供查询统计告警信息的方法
77 
78 
79 if __name__=="__main__":
80     wsgi_server=make_server(ALERTOR_CONFIG['bind_ip'],ALERTOR_CONFIG['port'],application)
81 
82     wsgi_server.serve_forever()

 

一时一刻此地先这么用,这么些模型的性质是基于uwsgi运营,2进度,各类进度内4个线程,基准质量是15000呼吁总的数量,5000客商端

生龙活虎、线程概论

 ab -n 15000-c 5000 -p test_alert.txt -T application/x-www-form-urlencoded ""

1、何为线程

效果与利益还集中吧。

每一种进程有一个地方空间,并且暗中认可就有二个调控线程。假如把四个进度比喻为叁个车间的劳作经过那么线程就是车间里的三个三个流程。

进度只是用来把财富聚焦到协同(进程只是叁个能源单位,可能说能源集合),而线程才是cpu上的实行单位。

八线程(即五个控制线程)的概念是,在二个经过中留存七个调节线程,三个调节线程分享该进程之处空间(资源)

创办进度的开垦要远超越线程开进程也就是建叁个车间,而开线程约等于建一条流水生产线。

2、线程和经过的区分

1.Threads share the address space of the process that created it; processes have their own address space.
2.Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.
3.Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
4.New threads are easily created; new processes require duplication of the parent process.
5.Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
6.Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes.

中译:

1、线程共享创建它的进程的地址空间;进程有自己的地址空间。
2、线程可以直接访问其进程的数据段;进程有它们自己的父进程数据段的副本。
3、线程可以直接与进程的其他线程通信;进程必须使用进程间通信来与兄弟进程通信。
4、新线程很容易创建;新进程需要复制父进程。
5、线程可以对同一进程的线程进行相当大的控制;进程只能对子进程执行控制。
6、对主线程的更改(取消、优先级更改等)可能会影响该进程的其他线程的行为;对父进程的更改不会影响子进程。

3、多线程的亮点

四线程和多进程相像指的是,在叁个进度中拉开多少个线程

1)多线程分享一个进程的地址空间(财富)

2) 线程比进度更轻量级,线程比进度更便于成立可收回,在重重操作系统中,成立三个线程比创设一个历程要快10-100倍,在有恢宏线程须求动态和便捷更正时,那豆蔻梢头特征很有用

3) 若七个线程皆以cpu密集型的,那么并不可能得到属性上的增高,不过只要存在大气的计量和大气的I/O管理,具有三个线程允许这么些活动竞相肥胖运维,进而会加速程序实施的快慢。

4) 在多cpu系统中,为了最大限度的采纳多核,能够开启四个线程,比开进度开销要小的多。(这一条并不适用于python)


 

二、python的面世编制程序之十二线程

1、threading模块介绍

multiprocessing模块的通通效仿了threading模块的接口,二者在动用范围,有异常的大的相符性,因此不再详细介绍

对multiprocessing模块亦非很熟练的冤家能够复习一下五十多线程时介绍的小说:

30、进程的幼功理论,并发(multiprocessing模块):

法定文书档案:(印度语印尼语好的能够尝尝挑衅)

2、开启线程的两种艺术(和进度一模二样)

三种办法里大家都有展开进度的艺术能够大约复习回想

1)方式一:

from threading import Thread
#from  multiprocessing  import  Process
import os
def talk():
    print('%s is running' %os.getpid())

if __name__ == '__main__':
    t=Thread(target=talk)
    # t=Process(target=talk)
    t.start()
    print('主',os.getpid())

2)方式二:

#开启线程
from threading import Thread
import os
class MyThread(Thread):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        print('pid:%s name:[%s]is running' %(os.getpid(),self.name))

if __name__ == '__main__':
    t=MyThread('lln')
    t.start()
    print('主T',os.getpid())

#开启进程
from multiprocessing import Process
import os
class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):
        print('pid:%s name:[%s]is running' % (os.getpid(), self.name))
if __name__ == '__main__':
    t=MyProcess('lll')
    t.start()
    print('主P',os.getpid())

3、在叁个进程下展开多少个线程与在叁个经过下展开多少个子进程的界别

1)相比较速度:(看看hello和主线程/主进度的打印速度)

from threading import Thread
from multiprocessing import Process
import os

def work():
    print('hello')

if __name__ == '__main__':
    #在主进程下开启线程
    t=Thread(target=work)
    t.start()
    print('主线程/主进程')

    #在主进程下开启子进程
    t=Process(target=work)
    t.start()
    print('主线程/主进程')

版权声明:本文由bob体育app发布于bob体育app,转载请注明出处:python3.x 多路IO复用补充asyncio