美文网首页
Python多线程

Python多线程

作者: 晨畿茨 | 来源:发表于2018-07-26 10:27 被阅读0次

    Python多线程

    多任务不仅可以使用多进程完成,也可使用多线程完成。
    一个进程可以包含很多线程,但至少含有一个线程。

    Python提供了 _thread和threading两个模块,供我们使用多线程。_thread是低级模块,threading是高级模块。我们通常使用threading来实现多线程的相关功能。

    使用线程读取文件内容。

    1. 读取文件内容的方法
    2. 创建线程,并将方法绑定到线程上
    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-  
    '多线程'
    __author__ = 'click'
    __date__ = '2018/7/23 下午6:20'
    
    import time, threading
    
    
    def threadReadFile():
        print('主线程的名字%s' % threading.current_thread().name)
        # print('读取文件中内容是%s' % myio.ReadAndWrite.readTxt())
        n = 0
        while n < 10:
            n = n + 1
    
        print('执行相加操作结果是%s' % n)
    
    
    t = threading.Thread(target=threadReadFile, name='threadReadFile')
    t.start()
    t.join()
    print("当前线城是%s" % threading.current_thread().name)
    
    

    运行结果:

    主线程的名字threadReadFile
    执行相加操作结果是10
    当前线城是MainThread
    

    使用线程之前,先<font color = red >import threading</font>要使用的threading模块。

    t = threading.Thread(target=threadReadFile, name='threadReadFile')
    

    初始化一个线程。

    target:指定线程要执行的任务。

    name:创建的线程的名称。

    这样就实现了新创建一个线程,执行新任务。

    提到多线程,就要考虑多线程之间操作同一变量时候,出现<font color = red >脏数据</font>的问题。

    来看看多线程是怎么样操作变量数据,导致多线程获取数据时候出错的。

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-  
    '多线程锁的问题'
    __author__ = 'click'
    __date__ = '2018/7/24 下午3:46'
    
    import time, threading
    
    '出现多线程数据混乱的问题:线程之间共享创建的全局变量' \
    '多进程之间的变量:进程间相互独立的,不存在多进程操作同一变量' \
    '多线程:共享同一变量,存在多线程对同一变量操作的情况'
    
    #####################################
    '多线程造成变量数据改变的原因' \
    '原因是因为高级语言的一条语句在CPU执行时是若干条语句,即使一个简单的计算:'
    'balance = balance + n'
    '也分两步:'
    
    '计算balance + n,存入临时变量中;'
    '将临时变量的值赋给balance。'
    '也就是可以看成:'
    
    'x = balance + n'
    'balance = x' \
        ####################################
    '使用线程锁,对操作变量的方法进行加锁,保证变量值发生改变时只有一个线程对其操作。单线程的模式'
    
    balance = 0
    
    # 初始化一个锁
    # 1. lock = threading.Lock()
    
    
    def change_it(n):
        global balance
        balance = balance + n
        balance = balance - n
    
    
    def run_thread(n):
        for i in range(1000000):
            # 1.首先申请锁
            # lock.acquire()
            try:
                change_it(n)
            finally:
                # 使用try  finaly 保证执行完之后,释放锁
               # lock.release()
    
    
    t1 = threading.Thread(target=run_thread, args=(4,))
    t2 = threading.Thread(target=run_thread, args=(6,))
    
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print('balance %s' % balance)
    
    

    先把锁相关的代码注释掉。

    运行结果:

    balance 4
    

    按照代码正常的逻辑应该是如下:

    n=4情况:
    banlance =0
    banlance = banlance+4  ->= banlance = 0+4 = 4
    banlance = banlance-4  ->= banlance = 4-4 = 0
    
    n=6情况:
    banlance = 0
    banlance = banlance +6 ->= banlance = 0+6 = 6
    banlance = banlance -6 ->= banlance = 6-6 = 0
    
    

    最后执行的结果banlance应该是0

    那为什么会是4 呢?

    创建多线程时候,应该按照先相加后相减。但是由于线程的调度是由操作系统直接控制。当t1,t2执行时,会出现<font color = red>交替执行</font>的情况。这样最后banlance的值就不等于0。

    这里面具体的原因是高级语言在执行一下代码时候,分为两部分执行,

    banlance = banlance+n
    1.计算banlance+n,并将值赋值给临时变量
    2.将临时变量赋值给banlance
    
    

    这样我们就清楚了,因为操作系统在执行代码时候分两步,当多线程执行时候,就会出现

    t1
    banlance = 0 
    banlance = banlnace +4 ->= x = 0+4 = 4
    
    t2
    banlance = 0 
    banlance = banlance +6 ->= Y = 0+6 = 6
    
    最终
    banlance = Y
     
    

    当t1代码开始运行到banlance = X时候,banlance = 4。对于t2任务 banlance的数据已经是错的了。

    综上,多线程导致数据出现错误的原因是,多个线程同时操作同一个变量,导致变量的值出现错误。

    所以,我们要保证在t1在操作banlance的时候,其他的线程就不能操作banlance,其他的线程就要等待。只有当t1执行完毕,并释放了对banlance的锁,其他的线程才能进行操作banlance变量。

    如何对一个变量进行加锁,

    • 初始化一个锁
      lock=threading.Lock()
    • 获取锁
      lock.acquire()
    • 将要执行的代码使用try...finaly处理,并在finaly中释放锁 lock.realease()

    也就是放开上述代码中的1、2、3处代码。

    运行代码结果为:

    banlance = 0
    

    多线程

    加锁

    相关文章

      网友评论

          本文标题:Python多线程

          本文链接:https://www.haomeiwen.com/subject/tgivmftx.html