一、在使用python多线程之前,你需要知道的。
python的多线程中,实现并发是没有问题的,但是!!是无法实现真正的并行的。
这是因为python内部有个GIL锁(全局解释器锁),这个锁限制了在同一时刻,同一个进程中,只能有一个线程被运行!!!
二、threading模块的基本使用方法。
可以使用它来创建线程。有两种方式来创建线程。
1、通过继承Thread类,重写它的run方法。
2、创建一个threading.Thread对象,在它的初始化函数__init__中将可调用对象作为参数传入。
3、接下来演示下这两种创建线程对象的方法。
- 通过继承Thread类的方式创建线程。
#!/usr/local/bin/python2.7
# -*- coding:utf-8 -*-
import threading
import time
class Mythread(threading.Thread):
def __init__(self,num):
threading.Thread.__init__(self)
self.num = num
def run(self):
print "running number %s" %(self.num)
time.sleep(3)
t1 = Mythread(1111111)
t2 = Mythread(2222222)
t1.start() #调用线程对象的start方法,类中的run方法就会被执行!!!!
t2.start()
print "ending"
2.创建一个threading.Thread对象,在实例化对象时调用构造方法来创建线程。
import threading
import time
def print_num(num):
print "running num is %s" %(num)
time.sleep(3)
print "running num is %s over!!!!" %(num)
if __name__ == "__main__":
t1 = threading.Thread(target=print_num,args=(111111,)) #创建线程对象
t2 = threading.Thread(target=print_num,args=(222222,)) #创建线程对象。
t1.start() #运行线程对象
t2.start()
print "ending"
#当前执行的python程序是一个主线程,在程序中执行的两个线程就是子线程。
三、关于线程对象的一些常用方法。
- join()执行了线程的join方法后,在子线程运行结束之前,父线程会被一直阻塞。
import threading
import time
def listen_music(name):
print "begin listenning to %s.%s" %(name,time.ctime())
time.sleep(3)
print "end listenning time %s" %(time.ctime())
def play_game(name):
print "play %s time %s " %(name,time.ctime())
time.sleep(8)
print "end playing"
thread_list = []
t1 = threading.Thread(target=listen_music,args=("mirrorcle world",))
t2 = threading.Thread(target=play_game,args=("Virtual stalker",))
t1.start()
t1.join() #当t1没有执行完之前,父线程会被阻塞,直到t1执行结束后,主线程(主程序)的代码才会继续执行。
t2.start()
t2.join() #当t2没有执行完之前,父线程会被阻塞,直到t2执行结束后主线程(主程序)的代码才会继续执行。
print "ending......."
2.setdeamon()设置守护线程。
首先先来了解下守护线程的概念。
我们用python写的程序,在运行的过程中,会开启一个主线程,如果这个主线程开启了一个子线程,主线程和子线程会兵分两路,分别运行。
默认情况下,当我们的python程序运行结束,准备退出的时候,会校验子线程是否运行完毕,如果子线程没有运行完毕,主线程会等待子线程运行完毕后,在退出,这是默认情况。
假如,我们现在有一种需求,只需要主线程运行结束后,不管子线程是否运行结束,都要和主线程一起结束,这就是守护线程的概念。
import threading
import time
def listen_music(name):
print "begin listenning to %s.%s" %(name,time.ctime())
time.sleep(3)
print "end listenning time %s" %(time.ctime())
def play_game(name):
print "play %s time %s " %(name,time.ctime())
time.sleep(8)
print "end playing"
thread_list = []
t1 = threading.Thread(target=listen_music,args=("mirrorcle world",))
t2 = threading.Thread(target=play_game,args=("Virtual stalker",))
t1.setDaemon(True) #守护线程一定要设置在start之前!!!
t1.start()
t2.setDaemon(True)
t2.start()
print "ending......."
运行结果:
begin listenning to mirrorcle world.Thu May 11 10:26:23 2017
play Virtual stalker time Thu May 11 10:26:23 2017
ending.......
从结果中可以看出两个线程的内容并没有被执行完!主线程执行结束后,子线程也跟着结束了!
四、关于线程对象的一些其他方法。
isAlive() 用来判断一个线程是否处于活动状态。
getName() 返回这个线程的线程名称。
setName()设置一个线程的名称。
threading 模块提供的一些函数:
threading.currentThread()返回当前线程对象。
threading.enumerate() 将当前python程序中正在运行的线程对象,以列表的形式返回。
threading.activeCount() 返回当前运行的线程数量。