去发现生活中的美好,记录生活中的点点滴滴

python多线程的使用(thread和threading)

python admin 75℃

多线程相比单线程,有什么优劣势呢?

1)多线程并发优点:在执行IO密集型任务时,某个任务阻塞的时候CPU会切换到其他任务就大大提高了CPU的使用效率。

2)多线程并发缺点:在执行计算密集型任务时,CPU一直在计算没有休息。因此python多线程并发并不能显著提高效率,但是使用多进程执行效率有所提升。

简单的说,多线程是充分利用硬件资源,提高并发数,但也不是开启的越多越好,在单核或者密集型计算任务时,多线程并不占多大优势。

thread
下面举例:

使用单线程执行:

# -*- coding: utf-8 -*-

import thread
from time import sleep,ctime
import random

def loop0(n):
    print 'start loop 0 :',ctime()
    sleep(n)
    print 'end  loop 0 :',ctime()

def loop1(n):
    print 'start loop 1 :',ctime()
    sleep(n)
    print 'end  loop 1 :',ctime()


def loop2(n):
    print 'start loop 2 :',ctime()
    sleep(n)
    print 'end  loop 2 :',ctime()

def main():
    loop0(1)
    loop1(2)
    loop2(3)

if __name__ == "__main__":
    print '--------------start main :', ctime()
    main()
    print '---------------end main  :', ctime()

执行结果,花费了6秒:

--------------start main : Fri May 29 17:41:25 2020
start loop 0 : Fri May 29 17:41:25 2020
end  loop 0 : Fri May 29 17:41:26 2020
start loop 1 : Fri May 29 17:41:26 2020
end  loop 1 : Fri May 29 17:41:28 2020
start loop 2 : Fri May 29 17:41:28 2020
end  loop 2 : Fri May 29 17:41:31 2020
---------------end main  : Fri May 29 17:41:31 2020

使用多线程执行:

# -*- coding: utf-8 -*-

import thread
from time import sleep,ctime

def loop0(n):
    print 'start loop 0 :',ctime()
    sleep(n)
    print 'end  loop 0 :',ctime()

def loop1(n):
    print 'start loop 1 :',ctime()
    sleep(n)
    print 'end  loop 1 :',ctime()


def loop2(n):
    print 'start loop 2 :',ctime()
    sleep(n)
    print 'end  loop 2 :',ctime()

def main():
    try:
        thread.start_new_thread(loop0, (1,)) #派生一个新的线程,传入方法名和参数
        thread.start_new_thread(loop1, (3,))
        thread.start_new_thread(loop2, (2,))
        return True
    except Exception as e:
        print e
        return False

if __name__ == "__main__":
    print '--------------start main :', ctime()
    main()
    sleep(7) #此方法,是保证子线程完成后,主线程才退出
    print '---------------end main  :', ctime()

执行结果,只花费了3秒:

--------------start main : Fri May 29 17:44:54 2020
start loop 0 :start loop 1 : start loop 2 : Fri May 29 17:44:54 2020 Fri May 29 17:44:54 2020
Fri May 29 17:44:54 2020

end  loop 0 : Fri May 29 17:44:55 2020
end  loop 2 : Fri May 29 17:44:56 2020
end  loop 1 : Fri May 29 17:44:57 2020
---------------end main  : Fri May 29 17:45:01 2020

以上对比,可以发现,使用多线程后,loop三个方法是同时开始,最后结束只花费了最长方法的3秒,大大提高了并发数。

但是我们发现,thread.start_new_thread(),在执行的时候,会报错:

Unhandled exception in thread started by 
sys.excepthook is missing
lost sys.stderr
Unhandled exception in thread started by 
sys.excepthook is missing
lost sys.stderr

这是因为子线程还没执行完,主线程就退出了,子线程执行完后发现老大走了,大喊一声:卧槽,人呢? 然后索性也就地卧倒了(异常退出),哈哈…
所以在执行的时候加上sleep(7) 、while(1)pass维持主线程,或者给每一个子线程加上一个锁,当所有锁都释放的时候再结束主线程,这里就不扩展了。

threading
接下来介绍threading,threading是thread的升级版,threading提供的是更高级的完全的线程管理。

低级别的thread模块是推荐给高手用,一般应用程序推荐使用更高级的threading模块:

1.它更先进,有完善的线程管理支持,此外,在thread模块的一些属性会和threading模块的这些属性冲突。

2.thread模块有很少的(实际上是一个)同步原语,而threading却有很多。

3.thread模块没有很好的控制主线程和子线程的关系,而threading会允许默认,重要的子线程完成后再退出。

举例:

# -*- coding: utf-8 -*-
import threading
from time import sleep,ctime


def loop0(n):
    print 'start loop 0 :',ctime()
    sleep(n)
    print 'end  loop 0 :',ctime()

def loop1(n):
    print 'start loop 1 :',ctime()
    sleep(n)
    print 'end  loop 1 :',ctime()


def loop2(n):
    print 'start loop 2 :',ctime()
    sleep(n)
    print 'end  loop 2 :',ctime()

def main():
    try:
        th = threading.Thread(target=loop0, args=(1,))
        th.start()

        th2 = threading.Thread(target=loop1, args=(2,))
        th2.start()

        th3 = threading.Thread(target=loop2, args=(3,))
        th3.start()

        return True
    except Exception as e:
        raise e


if __name__ == "__main__":
    print '--------------start main :', ctime()
    main()
    print '---------------end main  :', ctime()

执行结果:

--------------start main : Fri May 29 18:48:24 2020
start loop 0 : Fri May 29 18:48:24 2020
start loop 1 : Fri May 29 18:48:24 2020
---------------end main  :start loop 2 :  Fri May 29 18:48:24 2020Fri May 29 18:48:24 2020

end  loop 0 : Fri May 29 18:48:25 2020
end  loop 1 : Fri May 29 18:48:26 2020
end  loop 2 : Fri May 29 18:48:27 2020

可以看到,执行时间还是3秒,但是不需要额外维持主线程的运行,子线程一样可以完成。

threading常用方法:

run()	如果采用方法2创建线程就需要重写该方法
getName()	获得线程的名称(方法2中有示例)
setName()	设置线程的名称
start()	启动线程
join(timeout)
在join()位置等待另一线程结束后再继续运行join()后的操作,timeout是可选项,表示最大等待时间
setDaemon(bool)
True:当父线程结束时,子线程立即结束;False:父线程等待子线程结束后才结束。默认为False
isDaemon()	判断子线程是否和父线程一起结束,即setDaemon()设置的值
isAlive()
判断线程是否在运行

至此,thread和threding多线程的使用介绍完毕。

转载请注明:永盟博客 » python多线程的使用(thread和threading)

喜欢 (3)