zoukankan      html  css  js  c++  java
  • Python 模块(八) socketserver 以及 线程、进程

    目录

    • 异常处理
    • socketserver
    • 线程、进程

    一、异常处理


    try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
    代码示例:

    while True:
        n1 = input('input a number: ')
        n2 = input('input a number: ')
    
    
    
        try:
            n1 = int(n1)
            n2 = int(n2)
            res = n1 + n2
            print(res.sd)
            l = [1,2,3,4,]
            print(l[10])
    
            d = {1:'a',2:'b'}
            print(d[3])
            print('num:%s' %res)
        except ArithmeticError as e:    #引用属性错误
            print('ArithmeticError')
        except IndexError as e:        #下标错误
            print('IndexError')
        except KeyError as e:        #key错误
            print('KeyError')
        except ValueError as e:        #引用的值错误
            print('ValueError',e)
        except Exception as e:        #抛出绝大部分的错误
            print('异常错误')
            print(e)


    通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式。

    #自定义异常
    class DemoException(Exception):
        def __init__(self,msg):
            self.message = msg
        def __str__(self):
            return self.message
    a = 1
    try:
        #如果不满足该条件,抛出异常
        assert a == 1
    except DemoException as e:
        print(e)
    else:
        print('ok')
    #无论是否存在异常,都执行finally
    finally:
        print('over')

    二、sokectserver


    socketserver 是标准库中一个高级别的模块,用于简化网络客户与服务器的实现。
    1、要实现本模块,必须定义一个继承于基类BaseRequestHandler的处理程序类。BaseRequestHandler类的实例可以实现以下方法:
        1、h.handle() 调用该方法执行实际的请求操作。调用该函数可以不带任何参数,但是几个实例变量包含有用的值。h.request包含请求,h.client_address包含客户端地址,h.server包含调用处理程序的实例。对TCP之类的数据流服务,h.request属性是套接字对象。对于数据报服务,它是包含收到数据的字节字符串。
        2.h.setup()该方法在handle()之前调用。默认情况下,它不执行任何操作。如果希望服务器实现更多连接设置,可以在这里实现。
        3.h.finish()调用本方法可以在执行完handle()之后执行清除操作。如果setup()和 handle()都不生成异常,则无需调用该方法。
    2.服务器。要使用处理程序,必须将其插入到服务器对象。定义了四个基本的服务器类。
        1、TCPServer 支持ipv4的TCP协议的服务器。
        2、UDPServer 支持ipv4的UDP协议的服务器。
        3、UnixStreamServer 使用UNIX域套接字实现面向数据流协议的服务器,集成自TCPserver。
        4、UnixDatagramServer 继承自UDPServer

        四个服务器类的实例都有一下方法和变量:
        1、s.socket 用于传入请求的套接字对象
        2、s.server_address 监听服务器的地址
        3、s.RequestHandleClass 传递给服务器构造函数并由用户提供的请求处理程序类
        4、s.server_forever() 处理无线的请求
        5、s.shutdown() 停止server_forever()循环
        6、s.fileno() 返回服务器套接字的整数文件描述符。该方法可以有效的通过轮询操作实例

    代码实例

    server端
    #导入该模块
    import socketserver
    
    #定义一个类,继承socketserver.BaseRequestHandler
    class Server(socketserver.BaseRequestHandler):
        def handle(self):
        #打印客户端地址和端口
            print('New connection:',self.client_address)
        #循环
            while True:
            #接收客户发送的数据
                data = self.request.recv(1024)
                if not data:break#如果接收数据为空就跳出,否则打印
                print('Client data:',data.decode())
                self.request.send(data)#将收到的信息再发送给客户端
    
    if __name__ == '__main__’:
        host,port = '127.0.0.1’,8080  #定义服务器地址和端口
        server = socketserver.ThreadingTCPServer((host,port),Server) #实现了多线程的socket通话
        server.serve_forever()#不会出现在一个客户端结束后,当前服务器端就会关闭或者报错,而是继续运行,与其他的客户端继续进行通话。
    
    client端
    import socket
    ip_port = ('127.0.0.1',8080)
    sk = socket.socket()
    sk.connect(ip_port)
    
    while True:
        raw = input('>> ').strip()
        sk.send(bytes(raw,'utf8'))
        msg = sk.recv(1024)
        print(str(msg,'utf8'))
    sk.close()


    三、进程和线程



    1、定义
    进程是具有一定独立功能的程序,关于某个数据集合上的一次运行活动。进程是系统进行资源分配和调度的一个独立单位。
    线程是进程的一个实体,是CPU调度和分配的基本单位,它是比进程更小的能够独立运行的基本单位。线程不拥有系统资源,但是可以和同属一个进程的其他线程贡献进程所拥有的全部资源。
    2、关系
    一个线程可以创建和销毁另一个线程;同一个进程中的多个线程之间可以并发执行。
    3、最大差别在于它们是不同的资源管理方式。进程有独立的地址空间,一个进程崩溃后,不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但没有单独的地址空间。因此一个线程死掉等于整个进程死掉,多以多进程的程序要比多线程的程序强壮,但进程切换时耗费资源比较大。对于一些要求同事进行又要共享某些变量的并发操作,只能用线程,不能用进程。
    Python threading模块
    threading提供了一个比thread模块更高层的API来提供线程的并发性。这些线程并发运行并共享内存。
     一、Thread的使用
        目标函数可以实例化一个Thread对象,每个Thread对象代表着一个线程,可以通过start()方法,开始运行。
        有两种方式来创建线程:一种是通过继承Thread类,重写它的run方法;另一种是创建一个threading.Thread对象,在它的初始化函数(__init__)中将可调用对象作为参数传入。

    import threading
    import time
    
    def sayhi(num):
        print('running on nuber:%s' %num)
        time.sleep(3)
    
    if __name__ == '__main__':
    
        t1 = threading.Thread(target=sayhi,args=(1,))
        t2 = threading.Thread(target=sayhi,args=(2,))
    
        t1.start()
        t2.start()
    
        print(t1.getName())
        print(t2.getName())
    import threading
    import time
    
    def sayhi(num):
        print('running on nuber:%s' %num)
        time.sleep(3)
    
    if __name__ == '__main__’:
        t_list = []
        for i in range(20):
            t = threading.Thread(target=sayhi,args=[i,])
                t.start()
                t_list.append(t)
        for i in t_list:
            i.join()
        print('----done——')


    threading模块中的join函数
    该函数的作用主要是阻塞进程直到线程执行完毕。通用的做法是启动一批线程,最后join这些线程结束。
    原理就是一次检验线程池中的线程是否结束,没有结束就阻塞知道线程结束,如果结束则跳转执行下一个线程的join函数。




    end

  • 相关阅读:
    转:高层游戏引擎——基于OGRE所实现的高层游戏引擎框架
    转: Orz是一个基于Ogre思想的游戏开发架构
    转:Ogre源代码浅析——脚本及其解析(一)
    IntelliJ IDEA添加过滤文件或目录
    为什么要使用ConcurrentHashMap
    volatile关键字解析
    Spring Boot MyBatis 通用Mapper 自动生成代码
    使用mysql乐观锁解决并发问题
    使用Redis分布式锁处理并发,解决超卖问题
    浅析 pagehelper 分页
  • 原文地址:https://www.cnblogs.com/xiajie/p/5250675.html
Copyright © 2011-2022 走看看