使用多线程的方式
1、 函数式:使用threading模块threading.Thread(e.g target name parameters)
1 import time,threading 2 def loop(): 3 print("thread %s is running..." % threading.current_thread().name) 4 n = 0 5 while n < 5: 6 n += 1 7 print("thread %s is running... n = %s" % (threading.current_thread().name,str(n))) 8 time.sleep(1) 9 print("thread %s is over..." % threading.current_thread().name) 10 11 print("thread %s is running..." % threading.current_thread().name) 12 13 ts = [] 14 for i in range(5): 15 t = threading.Thread(target = loop, name = ‘loopThread ‘+ str(i)) 16 t.start() 17 ts.append(t) 18 for t in ts: 19 t.join() 20 print("thread %s is over..." % threading.current_thread().name)
多线程的输出:
thread MainThread is running... thread loopThread 0 is running... thread loopThread 0 is running... n = 1 thread loopThread 1 is running... thread loopThread 1 is running... n = 1 thread loopThread 2 is running... thread loopThread 2 is running... n = 1 thread loopThread 0 is running... n = 2 thread loopThread 1 is running... n = 2 thread loopThread 2 is running... n = 2 thread loopThread 0 is running... n = 3 thread loopThread 1 is running... n = 3 thread loopThread 2 is running... n = 3 thread loopThread 0 is running... n = 4 thread loopThread 1 is running... n = 4 thread loopThread 2 is running... n = 4 thread loopThread 0 is running... n = 5 thread loopThread 1 is running... n = 5 thread loopThread 2 is running... n = 5 thread loopThread 0 is over... thread loopThread 1 is over... thread loopThread 2 is over... thread MainThread is over...
python中得thread的一些机制和C/C++不同:在C/C++中,主线程结束后,其子线程会默认被主线程kill掉。而在python中,主线程结束后,会默认等待子线程结束后,主线程才退出。
python对于thread的管理中有两个函数:join和setDaemon
join:如在一个线程B中调用threada.join(),则threada结束后,线程B才会接着threada.join()往后运行。
setDaemon:主线程A启动了子线程B,调用b.setDaemaon(True),则主线程结束时,会把子线程B也杀死。【此段内容摘录自junshao90的博客】
2. 使用面向对象方式。创建子类继承自threading.Thread,需overwrite run方法
1 import time,threading 2 class threadTest(threading.Thread): 3 def __init__(self,tname): 4 threading.Thread.__init__(self) 5 self.name = tname 6 def run(self): 7 print("thread %s is running..." % threading.current_thread().name) 8 n = 0 9 while n < 5: 10 n += 1 11 print("thread %s is running... n = %s" % (threading.current_thread().name,str(n))) 12 time.sleep(1) 13 print("thread %s is over..." % threading.current_thread().name) 14 print("thread %s is running..." % threading.current_thread().name) 15 16 for i in range(3): 17 t = threadTest(‘t‘ + str(i)) 18 t.start() 19 t.join() 20 print("thread %s is over..." % threading.current_thread().name)
运行输出:
thread MainThread is running... thread t0 is running... thread t0 is running... n = 1 thread t0 is running... n = 2 thread t0 is running... n = 3 thread t0 is running... n = 4 thread t0 is running... n = 5 thread t0 is over... thread t1 is running... thread t1 is running... n = 1 thread t1 is running... n = 2 thread t1 is running... n = 3 thread t1 is running... n = 4 thread t1 is running... n = 5 thread t1 is over... thread t2 is running... thread t2 is running... n = 1 thread t2 is running... n = 2 thread t2 is running... n = 3 thread t2 is running... n = 4 thread t2 is running... n = 5 thread t2 is over... thread MainThread is over...
3. lock
多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响。
而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把 内容给改乱了。
lock 对象:
acquire():负责取得一个锁。如果没有线程正持有锁,acquire方法会立刻得到锁。否则,它闲意态等锁被释放。一旦acquire()返回,调用它的线程就持有锁。
release(): 释放锁。如果有其他线程正等待这个锁(通过acquire()),当release()被效用的时候,它们中的一个线程就会
被唤醒
以下内容摘自“廖雪峰的官方网站”
http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386832360548a6491f20c62d427287739fcfa5d5be1f000
balance为共享资源,多进程同时执行,一定概率结果为balance != 0[详细描述见原文]
def change_it(n): # 先存后取,结果应该为0: global balance balance = balance + n balance = balance - n
使用threading.Lock()
import threading total = 0 lock = threading.Lock() def change(n): global total total += n total -= n def run_thread(n): lock.acquire() for i in range(100000): change(n) lock.release() t1 = threading.Thread(target = run_thread, args=(5,)) t2 = threading.Thread(target = run_thread, args=(8,)) t1.start() t2.start() t1.join() t2.join() print(total)
4. 其他详细关于对进程的资料可参考
解决共享资源问题的:条件变量,同步队列
Vamei的博客Python标准库08 多线程与同步 (threading包)
片片灵感的博客Python多线程学习