这就是一个线程的基本使用方式,定义一个run方法 使用的时候创建线程对象,然后线程对象.start(),就表示开启这个线程,执行run方法 线程对象的创建方式是threading.Thread(target=run,ages=(参数1,参数2,))如果只是一个参数那这个参数也要有逗号 除了上面的方法来创建线程,还有使用类的方式来创建一个线程 创建一个类,然后实现Thread类,那么这个类就是线程类 运行的线程的时候,首先是创建一个线程对象,然后调用start方法来运行运行run方法 案例,计算50个线程的运行时间这个程序的思想是:开启50个线程,每个线程睡眠两秒钟,计算这50个线程的运行时间,如果不是多线程,那么每个两秒,50个那就是100秒,但是多线程让这50个只用2秒多一点 这个程序的关键是: 如何才能再50个线程执行完毕之后,才执行最后一句代码,计算出所有线程的执行时间 这就要保证50个线程只要不结束就不执行这一句 可以使用线程对象.join()方法,这个方法的意思是当前线程对象的run方法结束程序才往下走 比如t1.join()方法的意思是程序堵塞在这,什么时候t1线程执行完毕什么时候程序往下走 这个程序的的关键在于,只要创建一个线程就放入一个列表,然后遍历所有列表中的线程对象,每一个都join,也就是等待每一个线程都执行完毕,程序才往下执行,最终输出执行的时间 守护线程 以上代码就是设置当前线程为守护线程,守护是为主线程守护,只要主线程执行完毕,这些线程就不执行了 线程锁当多个线程共同操作同一个变量的时候,加锁可以保证数据的安全 在主线程中threading.lock()这个方法的意思是创建一个锁对象 lock.acquire()的意思是开启这个锁,哪个线程拿到这个锁之后,其它线程就拿不到了,只有等这个线程释放之后(lock.release()),才可以拿到这个锁进而执行这个锁后面的内容。 递归锁 threading.Lock()加载线程的锁对象,是一个基本的锁对象,一次只能一个锁定,其余锁请求,需等待锁释放后才能获取,也就是说下面的程序会出问题 这个程序会出问题,原因就是threadking.Lock()只能锁一次,就是说一个线程中只能被一次acquire,其余的锁请求只能在这一次释放之后才可以 分析程序t.start之后会开启run3线程此时锁定,run3内部调用run1(并没有开启线程),run1内部也想要锁,但是run3锁的那次还没有释放呢,所以他获取不到锁,该t线程就会堵塞在这里,所以下面的while循环就会一直执行,因为会一共有两个线程(包含主线程)会一直运行,永远不等于1,所以while不停止 解决这种情况需要:使用RLock()锁 threading.RLock() 多重锁,在同一线程中可用被多次acquire。如果使用RLock,那么acquire和release必须成对出现, 调用了n次acquire锁请求,则必须调用n次的release才能在线程中释放锁对象 既然可以锁多次,那么上面的程序在执行run1方法的时候,也可以获取到锁,所以程序不会堵塞,也会往下继续运行。 线程之信号量: 线程锁又叫互斥锁同时只允许一个线程修改数据,也就是一个线程获取到这个锁之后,其它的线程是获取不到这个锁的,只能等待,等待这个线程释放锁之后,哪个线程得到锁之后就可以继续执行,没有得到锁的线程将继续等待。 而Semaphore同时允许指定数量的线程获取这个锁,也就是说这个锁可以同时被多个线程所共用,比如设置可以3个共用锁,则3个线程可以一起运行锁之后的内部,释放一个就会有一个线程可以获取到锁。 如上面的程序,threading.BuondedSemaphore(5)的意思就是设置最多允许5个线程同时运行 线程之event: Event(事件):事件处理的机制:全局定义了一个内置标志Flag,就是内部核心是flag,如果Flag值为False,那么当程序执行event.wait方法时就会阻塞,如果Flag值为True,那么event.wait 方法时便不再阻塞。 Event没有锁,无法使线程进入同步阻塞状态。 Event()的方法
这个程序有两个线程,一个车线程一个红绿灯线程,车要根据红绿灯的情况进行行动,红绿灯会自动按照时间来来回回的变化,而车要根据红绿灯来来回回的变化,再两个线程传递信息的桥梁就是event 红绿灯规则是这样的,当count只要小于5就表示绿灯,event。set将标志位设置为true 5到10设置为红灯,event.clear将标志位设置为false 大于10,则count为0,并且社会绿灯event。set 这里面的所有情况都可以根据event来获取,所以车只要根据event就可以判断当前红绿灯的情况 车的判断: 只要event.isset就表示当前为绿灯,可以执行,如果不是则表示绿灯,此时应该等待,执行wait,此时堵塞,什么时候标志位为true,也就是绿灯的时候wait就不堵塞了,就可以往下运行了 |
|