Python异常处理和多线程

异常处理
异常在程序的运行过程中发生的不正常的事件,会中断正在运行的程序。

常见的内置异常
NameError 尝试访问一个未声明的变量
ZeroDivisionRrror 除数为零
SyntaxError 解释器语法错误
IndexError 请求的索引超出序列范围
KeyError 请求一个不存在的字典关键字
AttributeError 尝试访问未知的对象属性

异常结构

try:
    语句    #被监控异常的代码块    
except:
    语句    #异常处理的代码
finally:#通常用来释放占用的资源,例如:关闭文件,关闭数据库的链接

例子1:

num1 = int(input("第一个整数:"))
num2 = int(input("第一个整数:"))
try:
    shang = num1 / num2
    print("{0}/{1}={2}".format(num1,num2,shang))
except Exception as eo :
    print("有错误了{0}".format(eo))
finally:
    print("感谢使用")

例子2:

num1 = int(input("第一个整数:"))
num2 = int(input("第一个整数:"))
try:
    shang = num1 / num2
    print("{0}/{1}={2}".format(num1,num2,shang))
except (TypeError,ZeroDivisionError) as eo :
    print("有错误了{0}".format(eo))
finally:
    print("感谢使用")

异常继承结构
BaseException类是所有异常之母,
Exception类是其他异常子类的父类
例子
多重异常判断

    def aaa(obj):
        try:
            retval = float(obj)
        except ValueError as e:
            retval = "非数值类型数据不能转换为float数据"
        except TypeError as e:
            retval = "数据类型不能转换为float类型"
        except Exception as e:
            retval = "有异常"
        return retval
    print aaa("Hello world")
    print aaa("599.99")
    print aaa(200)
    print aaa(99.9)

抛出异常

在什么场合抛出异常?
除了系统自动抛出异常外,在s编程过程中,有些问题是系统无法发现并解决的,
例如程序要求文件名不能是“hello”,此时需要程序员自行抛出异常,把问题交给调用者解决,通过抛出异常,接收兵处理异常,实现程序的多分支处理

raise语句格式很多,常用格式

raise 异常类
raise 异常类(参数或元组)

例子:(不能输入“等等”这个名字,如果输入了等等这个名字会抛出异常)

def filename():
    filename = raw_input("Please input file name:")
    if filename == "等等":
        raise NameError("不能输入此姓名")
    return filename

while True:
    try:
        filename=filename()
        print "filename is %s"%filename
        break
    except NameError:
        print "请换一个名字重新输入:"

多线程
由于每个进程只要干一件事,所以,一个进程只要有一个线程,当然,想Word这种复杂的进程可以有多个线程,多个线程可以同时执行,多线程的执行方式和多线程是一样的,也是由操作系统在多个线程之间快速切换,让每个线程都短暂得交替运行,看起来就像同时执行一样

这里写图片描述

1.新建状态(New):

当用new操作符创建一个线程时, 例如new Thread(r),线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码

2.就绪状态(Runnable)
一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。

处于就绪状态的时候,并不是立即运行run()方法,而是线程同其他线程竞争CPU时间,获得CPU时间后才能运行,在单CPU的计算机系统中,不能同时运行多个线程,一个时刻只能有一个线程运行。所以,其他线程处于等待,

3.运行状态(Running)
当线程获得CPU时间后,它就可以进入运行状态,真正开始执行run()方法了.

4.阻塞状态(Blocked)
线程运行过程中,可能由于各种原因进入阻塞状态:
(1)>线程通过调用sleep方法进入睡眠状态;
(2)>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
(3)>线程试图得到一个锁,而该锁正被其他线程持有;
(4)>线程在等待某个触发条件;

5.死亡状态(Dead)
有两个原因会导致线程死亡:
1) run方法正常退出而自然死亡,
2) 一个未捕获的异常终止了run方法而使线程猝死。

线程操作涉及到的方法:(详细请查看http://www.cnblogs.com/tkqasn/p/5700281.html

对象:
类                   方法
Tread:            start 启动  join 加入新线程
Lock、Rlock:      acquire枷锁  release释放锁
Condition:        acquire枷锁  release释放锁 wait  notify  notif_all
Event:            set等同于notifAll   clear取消notifAll
timer:             sleep等同于java的sleep

Python3 线程中常用的两个模块为:
1._thread
2.threading(推荐使用)
thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用”thread” 模块。为了兼容性,Python3 将 thread 重命名为 “_thread”。

例子1:(这是一个简单的线程练习)

import threading   #导入模块threading
import time        #导入模块time

a=threading.Lock()  #获取枷锁
ca=threading.Condition(a) #给枷锁设置时间
def zheng():
    for i in range(1,31):
        print("zheng i={0}".format(i))  #从正序输出1-31
        if i > 10:
            ca.acquire()   #如果i>10 给ca上锁
            ca.notify()    #唤醒ca
            ca.release()   #释放枷锁ca
        if i > 25:
            t2.join()      #如果i>25,开始输出反序
        time.sleep(0.1)    #每输出一个睡一秒
def fan():
    ca.acquire()          #ca上枷锁
    ca.wait()             #ca等待同时释放枷锁
    ca.release()          #释放枷锁ca
    for i in range(30,0,-1):
        print("fan i={0}".format(i))  #从正序输出1-31
        time.sleep(0.1)   #每输出一个睡一秒

threading._start_new_thread(zheng,())  #创建线程
#threading._start_new_thread(fan,())
t2=threading.Thread(target=fan)        #创建线程
t2.start()                             #开始ts的线程

input()

例子2:
一共4个人和尚,其中一个做馒头,其他三个吃馒头,
要求:
1.当做馒头的时候,不能吃馒头
2.当吃馒头的时候不能做馒头
3.馒头上线30个
4.再吃馒头的时候不能出现一个馒头被多个和尚吃
5.不能出现吃的时候和尚吃出异常(如一个和尚永远也吃不上,或者一个和尚吃了一个不存在的馒头)

这个是Python版的吃馒头的,下面还有一版java版的

import threading
import time

mantous=[]
a=threading.Lock()
b=threading.Lock()
ca=threading.Condition(a)
cb=threading.Condition(b)
#伙夫的任务函数
def huofu(name):
    time.sleep(1)
    while True:
        ca.acquire()
        for i in range(1,31):
            mantous.append("第{0}个馒头".format(i))
            print("做好{0}个馒头".format(i))
            time.sleep(0.1)
        print("馒头做好了,叫醒吃货")
        ca.notify_all()
        ca.release()
        print("{0}去等待".format(name))
        cb.acquire()
        cb.wait()
        cb.release()
#吃货的任务函数
def chihuo(name):
    ca.acquire()
    ca.wait()
    ca.release()
    while True:
        m=None
        ca.acquire()
        if len(mantous)!=0:
             m=mantous.pop()
        else:
            print("没馒头了")
            cb.acquire()
            cb.notify()
            cb.release()
            ca.wait()
        ca.release()
        if m is not None:
            print("{0}吃{1}".format(name,m))
            time.sleep(1)
threading._start_new_thread(huofu,('大头和尚',))
threading._start_new_thread(chihuo,('白眉和尚',))
threading._start_new_thread(chihuo,('牛鼻子和尚',))
threading._start_new_thread(chihuo,('花和尚',))

input()

java版的吃馒头

package com.dsj101.thread;

import java.util.ArrayList;
import java.util.List;

public class Test {
    static  class ManTou{
        private int num;

        public ManTou(int num) {
            this.num = num;
        }

        @Override
        public String toString() {
            return "第"+num+"个";
        }
    }
    public static List<ManTou> manTous=new ArrayList<>();
    public static void main(String[] args) {

        new HuoFu("大头和尚").start();
        new ChiHuo("白眉和尚").start();
        new ChiHuo("牛逼和尚").start();
        new ChiHuo("花和尚").start();


    }
    //火夫
    static class HuoFu extends Thread{
        private String name;

        public HuoFu(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            while (true) {
                synchronized ("a") {
                    System.out.println(name + "开始蒸馒头");
                    for (int i = 0; i < 30; i++) {
                        manTous.add(new ManTou(i + 1));
                        System.out.println("做完第" + (i + 1) + "个码头");
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("馒头做好了,开始吃吧");
                    "a".notifyAll();
                }
                synchronized ("b") {
                    try {
                        System.out.println("我先去睡一会,没了叫我");
                        "b".wait();
                        System.out.println("我知道了开始做去");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }
    //吃货
    static class ChiHuo extends Thread{
        private String name;

        public ChiHuo(String name) {
            this.name = name;
        }

        @Override
        public void run() {
             synchronized ("a"){
                 try {
                     "a".wait();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
            ManTou m=null;
            while (true) {
                synchronized ("a") {
                    System.out.println(name + "开始吃馒头");

                    if (manTous.size() != 0) {
                        m = manTous.remove(0);
                    } else {
                        System.out.println(name + "发现没有馒头,叫醒火夫做馒头");
                        synchronized ("b"){
                            "b".notify();
                        }
                        try {
                            System.out.println("我等着呢,完事后叫我吃");
                            "a".wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }
                if (m != null) {
                    System.out.println(name + "消化馒头"+m.toString());
                    int rd = (int) (Math.random() * 2000 + 1000);
                    m = null;
                    try {
                        Thread.sleep(rd);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值