zoukankan      html  css  js  c++  java
  • 10 线程 协程 socketserver 基于udp的socketserver

    线程进程

    操作系统的作用:
    1.把硬件丑陋复杂的接口隐藏起来,为应用程序提供良好接口
    2.管理,调用进程,并且把进程之间对硬件的竞争变得有序化

    多道技术:
    1.产生背景:为了实现单cpu下的并发效果
    2.分为两部分:
    1:空间上的复用(必须实现硬件层面的隔离)
    2:时间上的复用(复用cpu的时间片)
    什么切换?
    1:正在执行的任务遇到的阻塞
    2:正在执行的任务运行时间过长

    进程:正在运行的一个过程/一个任务,由操作系统负责调用,然后由cpu负责执行
    程序:就是程序员写的代码
    并发:伪并行,单核+多道
    并行:只有多核才能实现真正的并行

    同步:打电话,一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行
    异步:发短信,一个进程在执行某个任务时,另外一个进程无需等待其执行完毕,就可以继续执行,当有消息返回时,系统会通知后者进行处理,这样可以提高执行效率

    进程的创建:
    1. 系统初始化
    2. 与用户交互
    3. 在执行一个进程的过程中调用(Popen,os.fork)
    4.批处理任务

    系统的调用:
    linux:fork
    win:CreateProcess

    linux的下的进程与windows下的区别:
    1:linux的进程有父子关系,是一种树形结构,windows没有这种关系
    2:linux创建新的进程需要copy父进程的地址空间,win下从最开始创建进程,两个进程之间就是不一样




    线程:一条流水线的执行过程是一个线程,一条流水线必须属于一个车间,一个车间的运行过程就是一个进程
    (一个进程内至少一个线程)
    进程是资源单位
    而线程才是cpu上的执行单位

    多线程:一个车间内有多条流水线,多个流水线共享该车间的资源(多线程共享一个进程的资源)

    线程创建的开销要远远小于进程

    为何要创建多线程?
    1. 共享资源
    2. 创建开销小

    多线程模拟文件编辑器

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    from threading import Thread
    msg_l=[]
    format_l=[]
    def talk():
        while True:
            msg=input('>>: ').strip()
            if not msg:continue
            msg_l.append(msg)
    
    def format():
        while True:
            if msg_l:
                res=msg_l.pop()
                res=res.upper()
                format_l.append(res)
    
    def save():
        while True:
            if format_l:
                res=format_l.pop()
                with open('db.txt','a',encoding='utf-8') as f:
                    f.write('%s
    ' %res)
    
    if __name__ == '__main__':
        t1=Thread(target=talk)
        t2=Thread(target=format)
        t3=Thread(target=save)
        t1.start()
        t2.start()
        t3.start()
    多线程模拟文件编辑器

    线程对象的其他方法

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    n=11111111111111111111111111111111111
    import time
    from threading import Thread
    import threading
    def work():
        time.sleep(2)
        print('%s say hello' %(threading.current_thread().getName()))
    
    
    if __name__ == '__main__':
        t=Thread(target=work)
        # t.setDaemon(True)
        t.start()
        t.join()
        print(threading.enumerate()) #当前活跃的线程对象,是一个列表形式
        print(threading.active_count()) #当前活跃的线程数目
        print('主线程',threading.current_thread().getName())
    线程对象的其他方法

    单线程实现并发爬取网页

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    import requests
    import time
    # response=requests.get('https://www.python.org')
    # print(response.status_code)
    # print(response.text)
    
    def get_page(url):
        print('GET page:%s' %url)
        response=requests.get(url)
        if response.status_code == 200:
            print(response.text)
    
    start_time=time.time()
    get_page('https://www.python.org')
    get_page('https://www.yahoo.com')
    get_page('https://www.github.com')
    stop_time=time.time()
    print('run time is :%s' %(stop_time-start_time)) #11.989685773849487
    
    
    
    
    
    
    
    
    
    from gevent import monkey;monkey.patch_all()
    import requests
    import time
    import gevent
    def get_page(url):
        print('GET page:%s' %url)
        response=requests.get(url)
        if response.status_code == 200:
            print(response.text)
    
    start_time=time.time()
    g1=gevent.spawn(get_page,url='https://www.python.org')
    g2=gevent.spawn(get_page,url='https://www.yahoo.com')
    g3=gevent.spawn(get_page,url='https://www.github.com')
    gevent.joinall([g1,g2,g3])
    stop_time=time.time()
    print('run time is :%s' %(stop_time-start_time)) #8.745500326156616
    单线程实现并发爬取网页

    单线程实现并发的socket服务端

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    from gevent import monkey;monkey.patch_all()
    from socket import *
    import gevent
    def server(ip,port):
        s = socket(AF_INET, SOCK_STREAM)
        s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        s.bind((ip,port))
        s.listen(5)
        while True:
            conn, addr = s.accept()
            print('client',addr)
            gevent.spawn(talk,conn,addr)
    
    def talk(conn,addr): #通信
        try:
            while True:
                res=conn.recv(1024)
                if not res:break
                print('client %s:%s msg:%s' %(addr[0],addr[1],res))
                conn.send(res.upper())
        except Exception:
            pass
        finally:
            conn.close()
    
    if __name__ == '__main__':
        server('127.0.0.1', 8080)
    单线程实现并发的socket服务端
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    
    from socket import *
    c=socket(AF_INET,SOCK_STREAM)
    c.connect(('127.0.0.1',8080))
    
    while True:
        msg=input('>>: ').strip()
        if not msg:continue
        c.send(msg.encode('utf-8'))
        res=c.recv(1024)
        print(res.decode('utf-8'))
    客户端

    socketserver实现并发

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    
    import socketserver
    #MyHandler(conn, client_address, s)
    class MyHandler(socketserver.BaseRequestHandler): #通讯循环
        def handle(self):
            while True:
                res=self.request.recv(1024)
                print('client %s msg:%s' %(self.client_address,res))
                self.request.send(res.upper())
    
    if __name__ == '__main__':
    
        s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyHandler)
        s.serve_forever() #链接循环
    socketserver实现并发

    协程

    import time
    def consumer(item):
        # print(item)
        x=111111
        y=22222222222
        z=3333333
        a='abasdfasdfasdfasdfasdf'
        b='123213asdfasdfsadfasdf'
        pass
    
    def producer(target,seq):
        for item in seq:
            target(item)
    
    start_time=time.time()
    producer(consumer,range(100000000))
    stop_time=time.time()
    print('run time is %s' %(stop_time-start_time))
    
    
    
    
    
    
    import time
    def consumer():
        # print(item)
        x=111111
        y=22222222222
        z=3333333
        a='abasdfasdfasdfasdfasdf'
        b='123213asdfasdfsadfasdf'
        while True:
            item=yield
    
    def producer(target,seq):
        for item in seq:
            target.send(item)
    
    g=consumer()
    next(g)
    start_time=time.time()
    producer(g,range(100000000))
    stop_time=time.time()
    print('run time is %s' %(stop_time-start_time))
    协程
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    from gevent import monkey;monkey.patch_all()
    import gevent
    import time
    def eat(name):
        print('%s eat food first' %name)
        # gevent.sleep(5)
        time.sleep(5)
        print('%s eat food second' % name)
    def play(name):
        print('%s play phone 1' %name)
        # gevent.sleep(6)
        time.sleep(6)
        print('%s play phone 2' %name)
    
    g1=gevent.spawn(eat,'egon')
    g2=gevent.spawn(play,name='egon')
    g1.join()
    g2.join()
    print('')
    协程gevent(遇到IO自动切换)

    基于udp的socket

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    
    import socketserver
    
    class MyUDPhandler(socketserver.BaseRequestHandler):
        def handle(self):
            client_msg,s=self.request
            s.sendto(client_msg.upper(),self.client_address)
    
    if __name__ == '__main__':
        s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyUDPhandler)
        s.serve_forever()
    多线的udp服务端
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    
    from socket import *
    s=socket(AF_INET,SOCK_DGRAM)
    s.bind(('127.0.0.1',8080))
    
    
    while True:
        client_msg,client_addr=s.recvfrom(1024)
        print(client_msg)
        s.sendto(client_msg.upper(),client_addr)
    服务端
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    
    from socket import *
    c=socket(AF_INET,SOCK_DGRAM)
    
    while True:
        msg=input('>>: ').strip()
        c.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
        server_msg,server_addr=c.recvfrom(1024)
        print('from server:%s msg:%s' %(server_addr,server_msg))
    客户端
  • 相关阅读:
    Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数
    Django框架之第五篇(模板层) --变量、过滤器(|)、标签(% %)、自定义标签、过滤器、inclusion_tag,模板的继承、模板的注入、静态文件
    Django框架学习易错和易忘点
    守护线程
    Thread其他属性和方法
    进程与线程的区别
    开启线程
    关闭屏幕输出分屏显示
    生产者消费者模型
    队列
  • 原文地址:https://www.cnblogs.com/menglingqian/p/7134363.html
Copyright © 2011-2022 走看看