Python 的多线程有两种实现方法:

函数,线程类

1.函数

调用 thread 模块中的 start_new_thread() 函数来创建线程,以线程函数的形式告诉线程该做什么


复制代码代码如下:



# -*- coding: utf-8 -*- 
 
 import thread 
 
 def f(name): 
 
   #定义线程函数 
 
   print "this is " + name 
 
   
 
 if __name__ == '__main__': 
 
   thread.start_new_thread(f, ("thread1",)) 
 
   #用start_new_thread()调用线程函数和其他参数 
 
   while 1: 
 
     pass

不过这种方法暂时没能找到其他辅助方法,连主线程等待都要用 while 1 这种方法解决。

2.线程类

调用 threading 模块,创建 threading.Thread 的子类来得到自定义线程类。


复制代码代码如下:



# -*- coding: utf-8 -*- 
 
 import threading 
 
 class Th(threading.Thread): 
 
   def __init__(self, name): 
 
     threading.Thread.__init__(self) 
 
     self.t_name = name 
 
     #调用父类构造函数 
 
   
 
   def run(self): 
 
     #重写run()函数,线程默认从此函数开始执行 
 
     print "This is " + self.t_name 
 
   
 
 if __name__ == '__main__': 
 
   thread1 = Th("Thread_1") 
 
   thread1.start() 
 
   #start()函数启动线程,自动执行run()函数


threading.Thread 类的可继承函数:
getName() 获得线程对象名称
setName() 设置线程对象名称
join() 等待调用的线程结束后再运行之后的命令
setDaemon(bool) 阻塞模式, True: 父线程不等待子线程结束, False 等待,默认为 False
isDaemon() 判断子线程是否和父线程一起结束,即 setDaemon() 设置的值
isAlive() 判断线程是否在运行

实例


复制代码代码如下:



import threading 
 
 import time 
 
 class Th(threading.Thread): 
 
   def __init__(self, thread_name): 
 
     threading.Thread.__init__(self) 
 
     self.setName(thread_name) 
 
   
 
   def run(self): 
 
     print "This is thread " + self.getName() 
 
     for i in range(5): 
 
       time.sleep(1) 
 
       print str(i) 
 
     print self.getName() + "is over"


join() 阻塞等待


复制代码代码如下:



if __name__ == '__main__': 
 
     thread1 = Th("T1 ") 
 
     thread1.start() 
 
     #thread1.join() 
 
     print "main thread is over"


不带 thread1.join() ,得到如下结果:


复制代码代码如下:



This is thread T1 
 
 main thread is over 
 
 0 
 
 1 
 
 2 
 
 T1 is over


不等待 thread1 完成,执行之后语句。


加了 thread1.join() ,得到如下结果:


复制代码代码如下:


This is thread T1 
 
 0 
 
 1 
 
 2 
 
 T1 is over 
 
 main thread is over


阻塞等待 thread1 结束,才执行下面语句

主线程等待


复制代码代码如下:


if __name__ == '__main__': 
 
   thread1 = Th("T1 ") 
 
   thread1.setDaemon(True) 
 
   #要在线程执行之前就设置这个量 
 
   thread1.start() 
 
   print "main thread is over"


报错: Exception in thread T1 (most likely raised during interpreter shutdown):
也就是主线程不等待子线程就结束了。

多个子线程


复制代码代码如下:



if __name__ == '__main__': 
 
     for i in range(3): 
 
         t = Th(str(i)) 
 
         t.start() 
 
     print "main thread is over"


这里的 t 可同时处理多个线程,即 t 为线程句柄,重新赋值不影响线程。

这里奇怪的是,运行 t.run() 时,不会再执行其他线程。虽不明,还是用 start() 吧。暂且理解为 start() 是非阻塞并行的,而 run 是阻塞的。

线程锁

threading 提供线程锁,可以实现线程同步。


复制代码代码如下:



import threading 
 
 import time 
 
 class Th(threading.Thread): 
 
   def __init__(self, thread_name): 
 
     threading.Thread.__init__(self) 
 
     self.setName(thread_name) 
 
   
 
   def run(self): 
 
     threadLock.acquire() 
 
     #获得锁之后再运行 
 
     print "This is thread " + self.getName() 
 
     for i in range(3): 
 
       time.sleep(1) 
 
       print str(i) 
 
     print self.getName() + " is over" 
 
     threadLock.release() 
 
     #释放锁 
 
 if __name__ == '__main__': 
 
   threadLock = threading.Lock() 
 
   #设置全局锁 
 
   thread1 = Th('Thread_1') 
 
   thread2 = Th('Thread_2') 
 
   thread1.start() 
 
   thread2.start()


得到结果:


复制代码代码如下:



This is thread Thread_1 
 
 0 
 
 1 
 
 2 
 
 Thread_1 is over 
 
 This is thread Thread_2 
 
 0 
 
 1 
 
 2 
 
 Thread_2 is over


import threading
from time import ctime,sleep


def music(func):
    for i in range(2):
        print "I was listening to %s. %s" %(func,ctime())
        sleep(1)

def move(func):
    for i in range(2):
        print "I was at the %s! %s" %(func,ctime())
        sleep(1)

threads = []
t1 = threading.Thread(target=music,args=(u'爱情买卖',))
threads.append(t1)
t2 = threading.Thread(target=move,args=(u'阿凡达',))
threads.append(t2)

if __name__ == '__main__':
    for t in threads:

        t.setDaemon(False)
        t.start()
    t.join()
    print "all over %s" %ctime()