Python 多线程Threading (一)

房东的猫 提交于 2020-03-02 19:01:52

不喜欢废话,先上今天的代码!

#-*- coding:utf-8 -*-
import threading
class MyThreading(threading.Thread):
    def __init__(self,num):
        threading.Thread.__init__(self)
        self.num  =  num
    def run(self):
        print self.num
        
        
t = MyThreading(100)
t.start()
print t.isAlive()

乍一看,很简单的threading代码。首先我们继承了Thread类,在子类里初始化后又重写了run方法。最后我们实例化MyThreading子类,然后打印我们的num参数。最后再打印线程执行状态。

初学者一看,绝对分为2派:1、支持说先打印num参数,然后才打印线程状态。 2、拍胸脯保证先打印线程状态再打印num参数;

 

其实结果出人预料:

结果1:

C:\Python27\python.exe D:/ProjectSpace/thread-example.py
100True
Process finished with exit code 0

 

结果2:

C:\Python27\python.exe D:/ProjectSpace/thread-example.py
True100
Process finished with exit code 0

 

 

吃惊吗?也许每次运行结果可能会有几次相同,但是在运行10次内,至少会有1-4次不同结果。

 

答案:线程的执行将是无序的

 

带着上面的问题,我们继续看下面一个例子:

 

#-*- coding:utf-8 -*-
import threading,time
class MyThreading(threading.Thread):
    def __init__(self,num):
        threading.Thread.__init__(self)
        self.num  =  num
    def run(self):
        time.sleep(10)
        print self.num
        
def function1():
    t1.start()
    time.sleep(1)
    print "t1 thread was Destruction "
    
def function2():
    t2.start()
    time.sleep(1)
    print "t2 thread was Destruction "
    
    
t1 = MyThreading(10)
t2 = MyThreading(20)
t2.setDaemon(True)
function1()
function2()

 

当你多次运行代码的时候,大概你能看到如下结果:

C:\Python27\python.exe D:/ProjectSpace/thread-example.py
t1 thread was Destruction 
t2 thread was Destruction 
10
Process finished with exit code 0

 

让我们看看单步调试运行下的结果是怎么样的:

C:\Python27\python.exe "C:\Program Files (x86)\JetBrains\PyCharm 5.0.3\helpers\pydev\pydevd.py" --multiproc --qt-support --client 127.0.0.1 --port 62267 --file D:/ProjectSpace/thread-example.py
Connected to pydev debugger (build 143.1559)
10
t1 thread was Destruction 
20
t2 thread was Destruction
Process finished with exit code 0

 

是的, 你没有看错! 出现不同的结果的原因是:

Threadclass.setDeamon方法指定了一个线程为主线程;而主线程的作用是当它要退出时会先检查子进程是否完成,如果未完成则继续等待,完成则退出。

 

这也是为什么我们在Debug模式时走的是逻辑上的方法,而实际上在运行时的结果却如上所述。

 

那么问题来了!:我们如何保证程序的顺序执行呢?

 

为了保证线程的执行顺序或者说是为了保证一致性,针对线程的操作引入了同步的概念。而针对同步最好的办法也就是对操作进行加锁了。(加锁让我想起了MySQL的锁  -  _ -)

请继续看下面的2个例子:

 

例1:

#-*- coding:utf-8 -*-
import threading,time
####继承Thread类
class MyThreading(threading.Thread):
    def __init__(self,name):
        ####初始化父类
        threading.Thread.__init__(self,name=name)
    def run(self):
        ####引入全局变量
        global x
        ####给操作加锁
        lock.acquire()
        for i in range(3):
            x = x + 1
        time.sleep(3)
        print x
        ####操作完成并解锁
        lock.release()
####实例化一个锁的类
lock = threading.RLock()
####定义一个空的线程类的列表
tl = []
####实例化10个类,并且将类添加到tl这个类列表里
for i in range(10):
    t = MyThreading(str(i))
    tl.append(t)
####初始化全局
x = 0
####逐个执行所有已经实例化的线程
for i in tl:
    i.start()

 输出结果如下

C:\Python27\python.exe D:/ProjectSpace/thread-example.py
3
6
9
12
15
18
21
24
27
30
Process finished with exit code 0

 

代码很简单,首先通过一个循环实例化10个类放进一个列表内,再从列表内遍历出来运行。 因为执行了加锁——》释放这个步骤。如果在time.sleep()时间内未到,release无法执行。所以我们能控制程序的顺序。

 

例2:

#-*- coding:utf-8 -*-
import threading,time
####继承Thread类
class MyThreading(threading.Thread):
    def __init__(self,name):
        ####初始化父类
        threading.Thread.__init__(self,name=name)
    def run(self):
        ####引入全局变量
        global x
        ####给操作加锁
        #lock.acquire()
        for i in range(3):
            x = x + 1
        time.sleep(3)
        print x
        ####操作完成解锁
        #lock.release()
####实例化一个锁的类
#lock = threading.RLock()
####定义一个空的线程类的列表
tl = []
####实例化10个类,并且将类添加到tl这个类列表里
for i in range(10):
    t = MyThreading(str(i))
    tl.append(t)
####初始化全局
x = 0
####逐个执行所有已经实例化的线程
for i in tl:
    i.start()

 输出结果如下

C:\Python27\python.exe D:/ProjectSpace/thread-example.py
30
30
30
30
30
30
30
30
30
30
Process finished with exit code 0

 

 同例1一样,程序从列表拿出实例化的类运行;但是因为没对run方法进行加锁,所以线程运行到time.sleep()时不会等待就启动第二个....第三个.....直到最后一个。

 而当run方法全部运行完毕后,并且计算出全局变量X的最终值,time.sleep时间到了;这时候X已经为30,所以每个X输出的值都是30了。

 

一个简单的Threading函数同步实例就说到这里! 下次见~~~   (— 3 —)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!