Python模块:threading

00x1 多线程基础讲解_↑↑↑↑↑↑↑↑↑↑↑↑↑

要使用多线程的函数可以实例化一个Thread对象,每个Thread对象代表着一个线程,可以通过start()方法,开始运行。

t = threading.Thread(target=worker) #将worker函数实例化为Thread对象

t.start() #实例化以后需要开始这个线程

由于python的多线程是伪多线程(并非真正意义的多线程)所以其线程并发出来的结果呈无规律状态。比如如下代码:

python 多线程并发为什么是伪并发 python 多线程假的_多线程

python 多线程并发为什么是伪并发 python 多线程假的_python 伪多线程_02

1 #!/usr/bin/python
2 #-*- coding: UTF-8 -*-
3 #by def
4
5 importthreading6
7 defqwe():8 print 1
9
10 a = threading.Thread(target=qwe)11 b = threading.Thread(target=qwe)12
13 a.start()14 b.start()15 print 'def'
View Code

按照我惯例最后print的应该是最后输出才对,但实际运行了并非如此

执行结果:

python 多线程并发为什么是伪并发 python 多线程假的_python 伪多线程_03

python 多线程并发为什么是伪并发 python 多线程假的_python_04

之所以说python的多线程是伪的多线程就是因为如此。真正的多线程好比花了好几个人同时去工作直至把他做完。而python只是一个人只做一点就丢给另外一个人。每个人做一点,所以在很多时候就会导致线程还没有执行完毕就执行线程以外的东西。这里就引进了一个join。相当于一个线程的分界线,告诉Thread给你的任务先做完了你才能执行下面的代码。不然就打死你。

如此代码:

python 多线程并发为什么是伪并发 python 多线程假的_Code_05

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#by def
import threading
def qwe():
print 1
a = threading.Thread(target=qwe)
b = threading.Thread(target=qwe) //两个线程
a.start()
b.start()
a.join()#加上join了以后就不会逾越这个分界线了b.join()print 'def'

python 多线程并发为什么是伪并发 python 多线程假的_Code_05

执行结果:

python 多线程并发为什么是伪并发 python 多线程假的_python 伪多线程_07

但当线程有参数的时候呢?

t = threading.Thread(target=worker,args=(i,))

python 多线程并发为什么是伪并发 python 多线程假的_多线程

python 多线程并发为什么是伪并发 python 多线程假的_python 伪多线程_02

1 #!/usr/bin/python
2 #-*- coding: UTF-8 -*-
3 #by def
4
5 importthreading6 importtime7 defa():8 time.sleep(2)9 print 'A Start'
10 time.sleep(2)11 print 'A End'
12 defb():13 time.sleep(2)14 print 'B Start'
15 time.sleep(2)16 print 'B End'
17 time1 =time.time()18 a()19 b()20 print time.time()-time121

22 没使用多线程案例 即为图一

View Code _1

python 多线程并发为什么是伪并发 python 多线程假的_多线程

python 多线程并发为什么是伪并发 python 多线程假的_python 伪多线程_02

1 #!/usr/bin/python
2 #-*- coding: UTF-8 -*-
3 #by def
4
5 importthreading6 importtime7 defa():8 time.sleep(2)9 print 'A Start'
10 time.sleep(2)11 print 'A End'
12 defb():13 time.sleep(2)14 print 'B Start'
15 time.sleep(2)16 print 'B End'
17 time1 =time.time()18 q = threading.Thread(target=a)19 w = threading.Thread(target=b)20 q.start()21 w.start()22 q.join()23 w.join()24 print time.time()-time125

26 使用多线程案例 即为图二

View Code _2

python 多线程并发为什么是伪并发 python 多线程假的_python 多线程并发为什么是伪并发_12

可见一个用了八秒一个用了四秒。

00x2的简单案例重的图重可以看出图二(使用了多线程)的输出是有问题的。再次证明了其伪多线程特征。那么他既然是一个人干一下活就丢给别人干,我们就让其干完了再干下一个活。这里就涉及到一个锁的概念。先关到小黑屋先干好了。然后再打开门。换另外一个小黑屋继续干。切记,【进屋子要关锁,出来的时候要开锁】(言下之意就是在你要执行的代码执行之前关锁,执行完了要把锁关上)

该种锁称之为“互斥锁”即LOCK,上锁:acquire 开锁:release

案例:

python 多线程并发为什么是伪并发 python 多线程假的_Code_05

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#by def
import threading
import time
mlock = threading.Lock()
def a():
mlock.acquire() #加上
time.sleep(2)
print 'A Start'
time.sleep(2)
print 'A End'
mlock.release() #开锁
q = threading.Thread(target=a)
q.start()

python 多线程并发为什么是伪并发 python 多线程假的_Code_05

题目:有10个刷卡机,代表建立10个线程,每个刷卡机每次扣除用户一块钱进入总账中,每个刷卡机每天一共被刷100次。账户原有500块。所以当天最后的总账应该为1500

答案:

python 多线程并发为什么是伪并发 python 多线程假的_Code_05

#encoding=utf-8
#by def
import threading
mLock = threading.Lock()
money = 500
def a():
global money
for i in xrange(100):
mLock.acquire()
money += 1
mLock.release()
l = []
for i in xrange(10):
t = threading.Thread(target=a)
t.start()
l.append(t)
for i in l:
t.join()
print money

python 多线程并发为什么是伪并发 python 多线程假的_Code_05