zoukankan      html  css  js  c++  java
  • day09进程与异常处理

    异常处理

    老师博客:http://www.cnblogs.com/linhaifeng/articles/6232220.html

    异常组成:

    Tracebace追踪信息(哪行出现了异常)、异常类型、异常的值

    异常类型:

    AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x

    IOError 输入/输出异常;基本上是无法打开文件

    ImportError 无法引入模块或包;基本上是路径问题或名称错误

    IndentationError 语法错误(的子类) ;代码没有正确对齐

    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]

    KeyError 试图访问字典里不存在的键

    KeyboardInterrupt Ctrl+C被按下

    NameError 使用一个还未被赋予对象的变量

    SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)

    TypeError 传入对象类型与要求的不符合

    UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它

    ValueError 传入一个调用者不期望的值,即使值的类型是正确的

    异常捕获到了以后判断是否是相关类型异常,如果是,执行except后面的代码

    万能异常

    try:
        # int("nit")
        print(ddd)
    except Exception as e:
        print(e)

    Ps:不能捕捉到语法异常

    什么时候要用异常?

    s1 = 'hello'

    try:

        int(s1)

    except IndexError as e:

        print(e)

    except KeyError as e:

        print(e)

    except ValueError as e:

        print(e)

    #except Exception as e:

    #    print(e)

    else:

        print('try内代码块没有异常则执行我')

    finally:

    print('无论异常与否,都会执行该模块,通常是进行清理工作')

    主动触发异常

    #_*_coding:utf-8_*_

    __author__ = 'Linhaifeng'

    try:

        raise TypeError('类型错误')

    except Exception as e:

        print(e)

    进程线程

      进程:正在进行的一个过程或者说一个任务,一个正在执行的过程,cpu来做这个任务。Cpu同一时刻只能做一个任务。所谓的看到cpu多并发是进程的执行与切换

    并行:同时运行,只有具备多个cpu才能实现并行

     并发:是伪并行,即看起来是同时运行。单个cpu+多道技术就可以实现并发,(并行也属于并发)

    参数介绍:

    group参数未使用,值始终为None

    target表示调用对象,即子进程要执行的任务

    args表示调用对象的位置参数元组,args=(1,2,'egon',)

    kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}

    name为子进程的名称

    创建进程:

    方法一

    from multiprocessing import Process
    import random
    def eat(name):
        print("%s want to eat" %name)
        food = ["bananan","apple","malon","lemon","peach"]
        print(random.choice(food))
        
    if __name__ == '__main__':
        p1 = Process(target=eat,args=("dodo",),name="eating")#复制进程创建新进程,("dodo",)这里一定要是一个元组
        p1.start()

        print("主进程")

    输出结果:

    主进程

    dodo want to eat

    Bananan

    Ps:父进程打印完为什么还要等着主进程,就是打印控制台还没有关闭

    如果父进程先结束,那么子进程就变成僵死进程,所以父进程一定要等着子进程。

    方法二

    class Eat(Process):
        def __init__(self,name1,name="Process1"):
            super().__init__()
            self.name1 = name1
            self.name=name
        def run(self):#自己定义的Process的进程类,一定要写run方法,p.start就是在调用run方法
            print("%s want to eat" % self.name1)
            food = ["bananan","apple","malon","lemon","peach"]
            print(random.choice(food))

    if __name__ == '__main__':
        p1 = Eat("dodo")
        p1.start()
        print("进程名:%s" %p1.name)
        print("主进程")

    输出结果:

    进程名:Process1

    主进程

    dodo want to eat

    Peach

    Process的方法:

    1join()等待子进程运行结束,再向下执行

    def eat(name):
        print("%s want to eat" %name)
        food = ["bananan","apple","malon","lemon","peach"]
        print(random.choice(food))

    if __name__ == '__main__':
        p1 = Process(target=eat,args=("dodo",),name="eating")
        p1.start()
        p1.join()#等待子进程运行结束,再向下执行
        print("主进程")

    输出结果:

    dodo want to eat

    malon

    主进程

    Ps:先启动的进程不一定先执行,要看哪个进程先建完,哪个进程先执行

    2daemon守护进程

    p1.start()前写 p1.Daemon = True

    父进程就可以终止子进程了,不需要等待子进程执行完 

    守护进程不可以再创建子进程

    from multiprocessing import Process,JoinableQueue
    import time,random
    def consumer(q,name):
        while True:
            # time.sleep(random.randint(1,3))
            res = q.get()
            q.task_done()
            # if res ==None:break
            print("消费者%s,拿到了%s" %(name,res))
    def product(seq,p,name):
        for item in seq:
            # time.sleep(random.randint(1, 3))
            q.put(item)
            print("%s生产了%s" %(name,item))
        # q.put(None)#结束方式一
        q.join()#方式二
        print("============>zhujincheng")

    if __name__ == '__main__':
        q=JoinableQueue()
        c= Process(target=consumer,args=(q,'egon'))
        c.daemon=True#守护进程,主进程结束,子进程也结束
        c.start()

        seq = ["包子%s" %i for i in range(10)]
        p= Process(target=consumer, args=(q, 'egon'))
        product(seq,p,"dodo")

    3、结束进程:

    P1.terminate()

    4、判断进程是否在

    P1.is_alive

    多进程实例

    服务端:

    from multiprocessing import Process
    from socket import *
    import logging
    logging.basicConfig(level=20,
                        format='%(module)s - %(asctime)s - %(levelname)s :  %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S %p',
                        handlers=[logging.FileHandler('server.log',encoding='utf-8',mode='a')])
    soc = socket(AF_INET,SOCK_STREAM)
    soc.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    soc.bind(("127.0.0.1",8080))
    soc.listen(5)
    # def talk(conn,addr):
    #     while True:
    #         try:
    #             msg = conn.recv(1024)
    #             if not msg:break
    #             logging.info("%s...发送消息【%s】" %(addr,msg.decode("utf-8")))
    #             conn.send(msg.upper())
    #         except Exception :
    #             break
    def write(conn,addr,Filename):
        while True:
            try:
                msg = conn.recv(1024)
                if not msg:break

                with open(Filename, 'a', encoding="utf-8") as f:
                    f.write(msg.decode("utf-8")+" ")
                    logging.info("%s...写入文件%s,写入内容【%s】" % (addr, Filename, msg.decode("utf-8")))
                    conn.send("写入成功".encode("utf-8"))
            except Exception :
                break

    if __name__ == '__main__':
        while True:
            conn,addr = soc.accept()#接受链接
            logging.info("[%s]......链接" %conn)
            # p = Process(target=talk,args=(conn,addr))
            p = Process(target=write, args=(conn,addr,"a.txt"))
            p.start()

    客户端:1——n都是一样的客户端

    from multiprocessing import Process
    from socket import *
    soc = socket(AF_INET,SOCK_STREAM)
    soc.connect(("127.0.0.1",8080))
    while True:
        msg = input(">>>").strip()
        if not msg:continue
        soc.send(msg.encode("utf-8"))
        res = soc.recv(1024)
        print(res.decode("utf-8"))

    IPC:进城之间通讯方式,基于消息

    线程之间可以直接通信,进程必须使用ipc才能通讯

    进程彼此之间互相隔离,要实现进程间通信,即IPCmultiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的

    Ipc是基于消息的通讯机制,管道和队列

    队列就是管道加锁实现的。

    队列:先进先出

    堆栈:先进后出

    from multiprocessing import Process,Queue
    q = Queue(3)#放三个值
    q.put('a')
    q.put('b')
    q.put('c')
    # q.put('d?')#会卡在这里,等着队列中的数据被取走一个才存进队列
    q.put('d?',False)#False ,不等待,满了就报异常,相当于put_nowait("d")
    1.put的参数:

    False(block = False)不等待,满了就报异常,相当于put_nowait("d")

    Timeout=2,两秒后报异常



    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())#会等待队列再放

    2.Get的参数:

    put

    q.put方法用以插入数据到队列中,put方法还有两个可选参数:blockedtimeout。如果blockedTrue(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blockedFalse,但该Queue已满,会立即抛出Queue.Full异常。

    q.get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blockedtimeout。如果blockedTrue(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blockedFalse,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常.

    1.q.get_nowait():q.get(False)

    2.q.put_nowait():q.put(False)

    3.q.empty():调用此方法时q为空则返回True,该结果不可靠,比如在返回True的过程中,如果队列中又加入了项目。

    4.q.full():调用此方法时q已满则返回True,该结果不可靠,比如在返回True的过程中,如果队列中的项目被取走。

    5.q.qsize():返回队列中目前项目的正确数量,结果也不可靠,理由同q.empty()q.full()一样

    生产者消费者模型(见守护进程)

    Manage进程之间实现数据共享

    from multiprocessing import Process,Manager
    import os
    def work(d,l):
        l.append(os.getpid())
        d[os.getpid()]=os.getpid()

    if __name__ == '__main__':
        m=Manager()#实现进程之间数据共享
        l=m.list(["egon"])
        d=m.dict({"name":"dodo"})
        p_l=[]
        for i in range(5):
            p = Process(target=work,args=(d,l))
            print(p)
            p.start()
            p_l.append(p)
        for i in p_l:
           i.join()
        print(d)
        print(l)
        print(p_l)
        print(m)

    输出结果:

    <Process(Process-2, initial)>

    <Process(Process-3, initial)>

    <Process(Process-4, initial)>

    <Process(Process-5, initial)>

    <Process(Process-6, initial)>

    {1088: 1088, 2864: 2864, 5044: 5044, 992: 992, 5708: 5708, 'name': 'dodo'}

    ['egon', 5708, 1088, 2864, 5044, 992]

    [<Process(Process-2, stopped)>, <Process(Process-3, stopped)>, <Process(Process-4, stopped)>, <Process(Process-5, stopped)>, <Process(Process-6, stopped)>]

    <multiprocessing.managers.SyncManager object at 0x0000000001190DD8>

    LOCK

    from multiprocessing import Process,Lock
    import random,time,json
    def work(name,lock):
        lock.acquire()#锁定了数据
        with open("a.txt",'r',encoding="utf-8") as f:
            dic = json.loads(f.read())
            if dic["count"]>0:
                dic["count"]-=1
                print("33[43m%s抢票成功33[0m" %name)
            else:
                print("33[46m%s抢票失败33[0m" % name)
        with open("a.txt",'w',encoding="utf-8")as f:
            f.write(json.dumps(dic))
        lock.release()#必须释放数据
    if __name__ == '__main__':
        lock = Lock()
        for i in range(100):
            p=Process(target=work,args=("用户%s" %i,lock))
            p.start()

    用进程池控制进程数:共享模块实现进程之间通讯

    Pool([numprocess  [,initializer [, initargs]]]):创建进程池

    参数

    1 numprocess:要创建的进程数,如果省略,将默认使用cpu_count()的值

    2 initializer:是每个工作进程启动时要执行的可调用对象,默认为None

    3 initargs:是要传给initializer的参数组

    方法

    p.apply同步的提交一个任务(同步:上一个任务不执行完下一步不执行),就是调用一个函数,建一个进程

    p.apply_async异步

    def write(conn,addr,Filename='a.txt'):
        while True:
            try:
                msg = conn.recv(1024)
                if not msg:break

                with open(Filename, 'a', encoding="utf-8") as f:
                    f.write(msg.decode("utf-8")+" ")
                    logging.info("%s...写入文件%s,写入内容【%s】" % (addr, Filename, msg.decode("utf-8")))
                    conn.send("写入成功".encode("utf-8"))
            except Exception :
                break

    if __name__ == '__main__':
        pool = Pool(1)#写几个进程,默认是cpu核数
        while True:
            conn,addr = soc.accept()#接受链接
            pool.apply_async(write,args=(conn,addr,))
            logging.info("[%s]......链接" %conn)

  • 相关阅读:
    递归练习题1
    爬虫模块之Beautiful Soup4
    python中的简易表格prettytable
    ubuntu中安装和使用quant-lib
    一个金融软件的基础功能分布
    ONLY_FULL_GROUP_BY 牛皮癣怎么治
    pandas
    pandas行筛选/列筛选(条件筛选/范围筛选)/计算
    conda 的 proxy设置
    openpyxl 安装失败的处理 (缺少 et_xmlfile )
  • 原文地址:https://www.cnblogs.com/doudouzheng/p/7101988.html
Copyright © 2011-2022 走看看