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的方法:

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

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:先启动的进程不一定先执行,要看哪个进程先建完,哪个进程先执行

2、daemon守护进程

在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")+"\n")
                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才能通讯

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

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方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。

q.get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,有两种情况存在,如果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("\033[43m%s抢票成功\033[0m" %name)
        else:
            print("\033[46m%s抢票失败\033[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")+"\n")
                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)

时间: 2024-10-11 21:04:30

day09进程与异常处理的相关文章

简单的进程解释--day09

body { max-width: 980px; border: 1px solid #ddd; outline: 1300px solid #fff; margin: 16px auto } body .markdown-body { padding: 45px } .markdown-body { color: #333333; overflow: hidden; font-family: "Helvetica Neue", Helvetica, "Segoe UI&qu

AIDL

AIDL的作用 在Android平台,每个应用程序都是一个单独的JVM,都运行在自己的进程空间里, 通常,一个进程不允许访问另一个进程的内存空间(一个应用不能访问另一个应用).当用户(程序开发人员)想在一个App中访问另一个App的进程空间的时候,就需要进程间通信.在Android中,远程服务为我们提供了实现进程间通信的方式,其中,AIDL是应用程序开发人员常的一种方式. AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在

Android 面试题(转)

转自:http://www.jobui.com/mianshiti/it/android/2682/ 1. Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念DVM指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例.而每一个DVM都是在Linux 中的一个进程,所以说可以认为是同一个概念.2.sim卡的EF 文件有何作用sim卡的文件系统有自己规范,主要是为了和手机通讯,sim本 身可以有自己的操作系统

OD: Memory Attach Technology - Exception

看到第六章了:形形色色的内存攻击技术 异常处理结构体 S.E.H Structure Exception Handler S.E.H 是 Windows 处理异常的重要数据结构.每个 S.E.H 为 8 字节:包含 S.E.H 链表指针和异常处理函数句柄(两个 DWORD). 1. S.E.H 存放在系统栈中,栈中一般会同时存放多个 S.E.H 2. 线程初始化时,会自动向栈中安装一个 S.E.H,作为线程默认的异常处理. 3. 如果程序源码中使用了 __try{}__except{} 或者 a

Android面试题目2

1. 请描述下Activity的声明周期. onCreate->onStart->onRemuse->onPause->onStop->onRestart->onDestroy 2. 如果后台的Activity由于某种原因被系统回收,如何在回收之前保存当前状态.onSaveInstanceState().程序中的某一个Activity A 在运行时,主动或被动的运行另一个新的Activity B,这个时候A会执行onSaveInstanceState().B完成以后又回

AndroidService 深度解析(2)

AndroidService 深度解析(2) 上一篇文章我们对Service的生命周期进行了测试及总结.这篇文章我们介绍下绑定运行的Service的实现. 绑定运行的Service可能是仅为本应用提供服务,称为本地Service:也可能为其他应用提供跨进程服务,即远程Service.下面分别进行介绍: 本地Service 如果Service只服务于本应用,那么我们只需要继承Binder类,定义我们需要实现的方法即可,当发起绑定连接时,Service将会在onBind方法中返回这个继承类的对象,使

Android 面试题(答案最全)

1. Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念DVM指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例.而每一个DVM都是在Linux 中的一个进程,所以说可以认为是同一个概念.2.sim卡的EF 文件有何作用sim卡的文件系统有自己规范,主要是为了和手机通讯,sim本 身可以有自己的操作系统,EF就是作存储并和手机通讯用的3.嵌入式操作系统内存管理有哪几种, 各有何特性页式,段式,段页,用到

android IPC及原理简介

什么是Android操作系统,所谓的Android:是基于Linux内核的软件平台和操作系统,早期由Google开发,后由开放手机联盟Open Handset Alliance)开发. Linux系统中进程间通信的方式有:socket, named pipe,message queque, signal,share memory.Java系统中的进程间通信方式有socket, named pipe等.android应用程序理所当然可以应用JAVA的IPC机制实现进程间的通信, 取而代之的是Bin

软件概要设计说明书—模板

1 引言 1.1 目的 介绍编写本文档的目的,主要内容及读者. 1.2 需求概述 描写叙述所要实现的功能和性能等. 1.3 名词及缩略语 列出文档中所用到的专门术语的定义和缩写词的原文. 1.4 參考资料 可包含: a. 项目经核准的计划任务书.合同或上级机关的批文. b. 项目开发计划. c. 需求规格说明书: d. 文档所引用的资料.标准和规范.列出这些资料的作者.标题.编号.发表日期.出版单位或资料来源. 參考资料清单 序号 名称 作者 编号 公布日期 查阅地点或渠道 出版单位(若不为本公