Python多线程的两种实现方式以及常用方法

Python多线程

  • 方法一:通过thread类实例化
    • start函数
    • setDaemon函数
    • join函数
  • 方法二:通过继承thread类

多线程和多进程的区别以及什么时候时候多线程,什么时候使用多进程这里就不做介绍了,直接开始讲解应用。这篇文章先讲解Python多线程的使用方法。

方法一:通过thread类实例化

start函数

start函数用于开始某个线程
定义两个函数,第一个函数耗时2秒,第二个函数耗时4秒,两个函数同时运行。观察运行结果

import threading
import time

#函数1
def doFirstThing(url):
    print("First Thing Star")
    time.sleep(2)
    print('First Thing Finished')

#函数2
def doSecondThing(url):
    print("Second Thing Star")
    time.sleep(4)
    print('Second Thing Finished')

if __name__ == "__main__":

	#传入threading
    thread1 = threading.Thread(target=doFirstThing,args=("",))
    thread2 = threading.Thread(target=doSecondThing, args=("",))
    start_time = time.time()
    
    thread1.start()
    thread2.start()

    end = time.time()
    print('time:%s'%(end-start_time))

运行结果

First Thing Star
Second Thing Star
time:0.0
First Thing Finished
Second Thing Finished

运行结果很奇怪,因为 计时应该在完成之后而不是完成之前,我们debug来看一下。
Python多线程的两种实现方式以及常用方法_第1张图片
debug可以看到这里实际上有三个线程,一个主线程MainThread和两个子线程Thread-7,Thread-6,程序在主线程结束之后并不会停止,而是会等到子线程也运行完之后才停止。而这三个线程又是独立运行的,所以时间输出在线程结束之前了


setDaemon函数

如果我们想让子线程会随着主线程结束而结束,就需要使用setDaemon函数设置守护线程。当线程设置了这个参数就会随着主线程的结束一起结束。

import threading
import time
def doFirstThing(url):
    print("First Thing Star")
    time.sleep(2)
    print('First Thing Finished')

def doSecondThing(url):
    print("Second Thing Star")
    time.sleep(4)
    print('Second Thing Finished')

if __name__ == "__main__":
    thread1 = threading.Thread(target=doFirstThing,args=("",))
    thread2 = threading.Thread(target=doSecondThing, args=("",))
    start_time = time.time()

    thread1.setDaemon(True)
    thread2.setDaemon(True)
    thread1.start()
    thread2.start()
    
    end = time.time()
    print('time:%s'%(end-start_time))

函数运行结果,可以看到没有 finished字样输出,因为随着主线程结束子线程也被强制结束掉了

First Thing Star
Second Thing Star
time:0.0


Process finished with exit code 0

join函数

但是这个结果并不是我们想看到的,我们想看到的是两个子线程同时运行,并且time约等于4,类似于两个函数并行的运行然后节约掉了2秒钟。这个时候就需要使用join函数了。使用了这个程序的主线程会被当前未运行完的线程阻塞掉,直到所有线程运行完毕。

import threading
import time
def doFirstThing(url):
    print("First Thing Star")
    time.sleep(2)
    print('First Thing Finished')

def doSecondThing(url):
    print("Second Thing Star")
    time.sleep(4)
    print('Second Thing Finished')

if __name__ == "__main__":
    thread1 = threading.Thread(target=doFirstThing,args=("",))
    thread2 = threading.Thread(target=doSecondThing, args=("",))
    start_time = time.time()

    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    end = time.time()
    print('time:%s'%(end-start_time))

这就是我们想看到的结果,运行时间4秒左右。相比起阻塞式编程,使用多线程节约了两秒。

First Thing Star
Second Thing Star

First Thing Finished
Second Thing Finished
time:4.002061605453491

Process finished with exit code 0

方法二:通过继承thread类

通过thread类继承并且重载run方法实际上可以达到和之前的写法一样的效果,但是对于一些较为复杂的逻辑,通过类完成多线程更容易维护。

import threading
import time
class doFirstThing(threading.Thread):
    def __init__(self,name):
        super().__init__(name=name)

    def run(self):
        print("First Thing Star")
        time.sleep(2)
        print('First Thing Finished')


class doSecondThing(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)

    def run(self):
        print("Second Thing Star")
        time.sleep(4)
        print('Second Thing Finished')

if __name__=="__main__":

    thread1 = doFirstThing('FirstThing')
    thread2 = doSecondThing('SecondThing')
    start_time = time.time()

    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    end = time.time()
    print('time:%s'%(end-start_time))

相同的结果

First Thing Star
Second Thing Star

First Thing Finished
Second Thing Finished
time:4.002086877822876

Process finished with exit code 0

你可能感兴趣的:(Python,Python高级编程)