线程
1.创建线程的第一种方法(后面讲解第二种方法)
导入:import threading
创建一个线程的执行计划:thd=threading.Thread(target=方法名)
启动线程:thd.start()
例子:
import threading import time def saySorry(): print("亲爱的,我错了,我能吃饭吗?") time.sleep(2) if __name__ == '__main__': for i in range(5): # 创建一个线程的执行的计划 thd=threading.Thread(target=saySorry) # 启动线程 thd.start()
开启线程,相当于一个进程中开启了五个分支,5个分支同时进行
2.查看当前进程内部存活的所有线程列表
threading.enumerate()
3.等待子线程执行结束之后主线程才继续执行(等待子线程完成之后,继续)
import threading def dance(): for i in range(5): print("正在跳舞... %d" %i) if __name__ == '__main__': thd=threading.Thread(target=dance) thd.start() print("太棒了")
执行结果:
但是有时候想子线程执行完之后才让主线程继续执行
就使用thd.join(),这个方法类似于主线程执行到这个位置,等待子线程结束才继续执行
import threading def dance(): for i in range(3): print("正在跳舞... %d" %i) if __name__ == '__main__': thd=threading.Thread(target=dance) thd.start() # 主线程阻塞等待 Thread对象标识的子线程退出之后 才会继续执行 thd.join() print("太棒了")
4.创建线程的第二种方法
1.创建一个类,并继承Thread
2.实现其中的run方法(run方法在Thread类中已经实现了,就相当于重写该方法,在这个run方法中就是子线程里运行的方法,相当于上面写的dance方法)
3.创建该类的实例对象
4.实例对象.start()启动创建和执行
import threading class myThread(threading.Thread): """1. 继承Thread 2. 实现其中run方法 3. 创建该类的实例对象 4. 对象.start()启动创建和执行""" def run(self): for i in range(3): print("在子线程中") if __name__ == '__main__': mt=myThread() mt.start() print("主线程")
5.多线程共享全局变量引起资源竞争混乱及解决方法
比如:火车票的数量,如果同时有3个人购买火车票,而火车票的数量是100张,当第一个人购买后火车票的数量就会变成99,此时数据库就会将100这个值修改成99,而第二个人也是在这一时刻购买火车票,此时第二个人的火车票数量也是100,提交的时候就变成了99,第三个人也同样是这样(就是说这三个人在同时刻同时修改数据库里的火车票数量),假设可以提交,那么实际上火车在数据库里的数量就是99,但是已经卖出去了3张,那么就会出现数据不准的情况。这就是全局变量引起的资源竞争混乱。
import threading # 全局变量 g_number=0 def add1(): global g_number for i in range(1000000): g_number+=1 def add2(): global g_number for i in range(1000000): g_number+=1 if __name__ == '__main__': th1=threading.Thread(target=add1) th1.start() th2=threading.Thread(target=add2) th2.start() th1.join() th2.join() print("结果:%d" %g_number)
这段代码,如果按照设想结果的话:g_number的结果是2000000
实际结果如下:
原因就是在某一刻时间内add1,add2获取g_number的时候值相同,但是提交结果都加1,然后一个值覆盖另一个值,那么就会出现这种情况
解决的方法:创建一个全局互斥锁,在一个线程修改这个全局变量的时候,不让别的线程修改,阻塞等待,如果修改完了,才让另一个线程修改这个全局变量值
import threading # 全局变量 g_number=0 # 创建一把全局互斥锁 g_lock=threading.Lock() def add1(): global g_number for i in range(1000000): g_lock.acquire() # 尝试获取并且加锁,如果没有被锁定,就可以被我锁定;如果被锁定了,阻塞等待直到成功获取并锁定 g_number+=1 g_lock.release() # 操作完g_number变量释放锁资源,也就是解锁 def add2(): global g_number for i in range(1000000): g_lock.acquire() g_number+=1 g_lock.release() if __name__ == '__main__': th1=threading.Thread(target=add1) th1.start() th2=threading.Thread(target=add2) th2.start() th1.join() th2.join() print("结果:%d" %g_number)
第二种实现的方法:
import threading # 全局变量 g_number=0 # 创建一把全局互斥锁 g_lock=threading.Lock() def add1(lock): global g_number for i in range(1000000): lock.acquire() # 尝试获取并且加锁,如果没有被锁定,就可以被我锁定;如果被锁定了,阻塞等待直到成功获取并锁定 g_number+=1 lock.release() # 操作完g_number变量释放锁资源,也就是解锁 def add2(lock): global g_number for i in range(1000000): lock.acquire() g_number+=1 lock.release() if __name__ == '__main__': th1=threading.Thread(target=add1,args=(g_lock,)) th1.start() th2=threading.Thread(target=add2,args=(g_lock,)) th2.start() th1.join() th2.join() print("结果:%d" %g_number)