继续今天的python学习
昨天我们说到了多线程共享数据(全局变量),那么今天我们就紧接着来说一下多线程不共享数据的使用方式
import threading
import time
def test1():
the_number = 0
for i in range(100):
the_number += 1
time.sleep(1)
print(threading.current_thread().name + "the_number = %d"%(the_number))
def test2():
the_number = 0;
for i in range(200):
the_number += 1
time.sleep(2)
print(threading.current_thread().name + "the_number = %d"%(the_number))
t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()
运行结果:
Thread-1the_number = 100
Thread-2the_number = 200
可以看到两个线程之间是互不影响的。
然后提到了一个死锁的问题,看如下代码:
import threading
class Thread1(threading.Thread):
def run(self):
if mutexA.acquire():
print("mutexA doing in 1")
if mutexB.acquire():
print("mutexB doing in 1")
mutexB.release()
mutexA.release()
class Thread2(threading.Thread):
def run(self):
if mutexB.acquire():
print("mutexB doing in 2")
if mutexA.acquire():
print("mutexA doing in 2")
mutexA.release()
mutexB.release()
mutexA = threading.Lock()
mutexB = threading.Lock()
if __name__ == "__main__":
t1 = Thread1()
t2 = Thread2()
t1.start()
t2.start()
首先两个线程对mutexA和mutexB进行了上锁,而后在线程内部有企图去抢对方的锁,但是之前的mutexA和mutexB已经被使用,所以两个线程不能再使用,于是程序就卡在了这里没办法继续,这样就是死锁的一种情况。
运行结果:
第一种:
mutexA doing in 1
mutexB doing in 1
mutexB doing in 2
mutexA doing in 2
-------------------
第二种:
mutexA doing in 1
mutexB doing in 2
第一种并没有被锁死,那么原因是什么呢?
我想应该是在线程运行时产生的时间差导致的,从运行结果上很容易看出
第二种就是出现死锁的情况了,然后程序一直会卡在这里,这样很危险,也会造成相当大的损失,所以在写程序的时候一定要避免死锁!!!
如何避免死锁的,课上提到了一种银行家算法,由于课上没有实现,今天暂且不谈,后续我会更新这个算法的细节。
接下来谈到的是一个异步的问题,首先,什么是异步呢,就是没有规定的不掉,程序谁先执行不一定,那么同步就是按照规定好的顺序去执行代码:
import threading
import time
def work1():
while True:
if lock1.acquire():
print("----1----")
lock2.release()
def work2():
while True:
if lock2.acquire():
print("----2----")
lock3.release()
def work3():
while True:
if lock3.acquire():
print("----3----")
time.sleep(1)
lock1.release()
lock1 = threading.Lock()
lock2 = threading.Lock()
lock2.acquire()
lock3 = threading.Lock()
lock3.acquire()
t1 = threading.Thread(target=work1)
t2 = threading.Thread(target=work2)
t3 = threading.Thread(target=work3)
t1.start()
t2.start()
t3.start()
运行结果:
----1----
----2----
----3----
----1----
----2----
----3----
----1----
----2----
----3----
----1----
----2----
----3----
----1----
----2----
----3----
可以看出来是按1,2,3的先后顺序来执行的,这就是同步
接着是耦合的问题,什么是耦合?老师课上举了一个例子,一个人做包子,一个人吃包子,吃包子的速度可能与做包子的速度不相同,那么这样就会产生一些问题,那么在程序中也一样,再运行爬虫时爬数据的速度和处理数据的速度不匹配会导致一些时间呗浪费,那么为了解决这样的问题,我们用到了queue模块中的Queue(队列)。