python实现多线程的方法
这篇文章将为大家详细讲解有关python实现多线程的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
python实现多线程的方法:
1、Thread直接创建子线程
首先可以使用 Thread 类来创建一个线程,创建时需要指定 target 参数为运行的方法名称,如果被调用的方法需要传入额外的参数,则可以通过 Thread 的 args 参数来指定。
importthreadingimporttimedeftarget(second):print(f'Threading{threading.current_thread().name}isrunning')print(f'Threading{threading.current_thread().name}sleep{second}s')time.sleep(second)print(f'Threading{threading.current_thread().name}isended')print(f'Threading{threading.current_thread().name}isrunning')foriin[1,5]:thread=threading.Thread(target=target,args=[i])thread.start()print(f'Threading{threading.current_thread().name}isended')
运行结果:
ThreadingMainThreadisrunningThreadingThread-1isrunningThreadingThread-1sleep1sThreadingThread-2isrunningThreadingThread-2sleep5sThreadingMainThreadisendedThreadingThread-1isendedThreadingThread-2isended
如果想要主线程等待子线程运行完毕之后才退出,可以让每个子线程对象都调用下 join 方法:
threads=[]foriin[1,5]:thread=threading.Thread(target=target,args=[i])threads.append(thread)thread.start()forthreadinthreads:thread.join()
运行结果:
ThreadingMainThreadisrunningThreadingThread-1isrunningThreadingThread-1sleep1sThreadingThread-2isrunningThreadingThread-2sleep5sThreadingThread-1isendedThreadingThread-2isendedThreadingMainThreadisended
2、继承Thread类创建子线程
另外也可以通过继承 Thread 类的方式创建一个线程,该线程需要执行的方法写在类的 run 方法里面即可。上面的例子的等价改写为:
importthreadingimporttimeclassMyThread(threading.Thread):def__init__(self,second):threading.Thread.__init__(self)self.second=seconddefrun(self):print(f'Threading{threading.current_thread().name}isrunning')print(f'Threading{threading.current_thread().name}sleep{self.second}s')time.sleep(self.second)print(f'Threading{threading.current_thread().name}isended')print(f'Threading{threading.current_thread().name}isrunning')threads=[]foriin[1,5]:thread=MyThread(i)threads.append(thread)thread.start()forthreadinthreads:thread.join()print(f'Threading{threading.current_thread().name}isended')
运行结果:
ThreadingMainThreadisrunningThreadingThread-1isrunningThreadingThread-1sleep1sThreadingThread-2isrunningThreadingThread-2sleep5sThreadingThread-1isendedThreadingThread-2isendedThreadingMainThreadisended
守护线程
在线程中有一个叫作守护线程的概念,如果一个线程被设置为守护线程,那么意味着这个线程是“不重要”的,这意味着,如果主线程结束了而该守护线程还没有运行完,那么它将会被强制结束。
在 Python 中我们可以通过 setDaemon 方法来将某个线程设置为守护线程:
importthreadingimporttimedeftarget(second):print(f'Threading{threading.current_thread().name}isrunning')print(f'Threading{threading.current_thread().name}sleep{second}s')time.sleep(second)print(f'Threading{threading.current_thread().name}isended')print(f'Threading{threading.current_thread().name}isrunning')t1=threading.Thread(target=target,args=[2])t1.start()t2=threading.Thread(target=target,args=[5])t2.setDaemon(True)t2.start()print(f'Threading{threading.current_thread().name}isended')
运行结果:
ThreadingMainThreadisrunningThreadingThread-1isrunningThreadingThread-1sleep2sThreadingThread-2isrunningThreadingThread-2sleep5sThreadingMainThreadisendedThreadingThread-1isended
互斥锁
在一个进程中的多个线程是共享资源的,比如在一个进程中,有一个全局变量 count 用来计数,现在声明多个线程,每个线程运行时都给 count 加 1,代码实现如下:
importthreadingimporttimecount=0classMyThread(threading.Thread):def__init__(self):threading.Thread.__init__(self)defrun(self):globalcounttemp=count+1time.sleep(0.001)count=tempthreads=[]for_inrange(1000):thread=MyThread()thread.start()threads.append(thread)forthreadinthreads:thread.join()print(f'Finalcount:{count}')
运行结果:
Finalcount:69
由于 count 这个值是共享的,每个线程都可以在执行 temp = count 这行代码时拿到当前 count 的值,但是这些线程中的一些线程可能是并发或者并行执行的,这就导致不同的线程拿到的可能是同一个 count 值,最后导致有些线程的 count 的加 1 操作并没有生效,导致最后的结果偏小。
所以,如果多个线程同时对某个数据进行读取或修改,就会出现不可预料的结果。为了避免这种情况,我们需要对多个线程进行同步,要实现同步,我们可以对需要操作的数据进行加锁保护,这里就需要用到 threading.Lock 了。
加锁保护
某个线程在对数据进行操作前,需要先加锁,这样其他的线程发现被加锁了之后,就无法继续向下执行,会一直等待锁被释放,只有加锁的线程把锁释放了,其他的线程才能继续加锁并对数据做修改,修改完了再释放锁。
这样可以确保同一时间只有一个线程操作数据,多个线程不会再同时读取和修改同一个数据。
关于python实现多线程的方法就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。