• python threading 锁的应用


    如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。锁有两种状态——锁定和未锁定。每当一个线程比如"set"要访问共享数据时,必须先获得锁定;如果已经有别的线程比如"print"获得锁定了,那么就让线程"set"暂停,也就是同步阻塞;等到线程"print"访问完毕,释放锁以后,再让线程"set"继续。

    一、(1)未采用锁,线程1与线程2并行执行。

    import threading
    from time import sleep,ctime
    
    class MyThread(threading.Thread):
        def __init__(self, func, arg):
            super(MyThread, self).__init__()
            self.func = func
            self.arg = arg
        # 重写run()方法
        def run(self):
            """
            threadLock.acquire() #获取锁,用于线程同步
            """
            self.func(self.arg)
    
            """
            threadLock.release()#释放锁,开启下一个线程
            """
    
    def f(n):
        for i in range(n):
            sleep(1)
            print(i,threading.current_thread().name,ctime())
    
    """
    threadLock = threading.Lock()
    """
    
    for i in range(2):
        thread = MyThread(f,5)
        thread.start()

    输出如下:

    00  Thread-1Thread-2  Mon Oct 26 19:52:12 2020Mon Oct 26 19:52:12 2020
    
    11  Thread-1 Thread-2Mon Oct 26 19:52:13 2020 
    Mon Oct 26 19:52:13 2020
    22  Thread-1Thread-2  Mon Oct 26 19:52:14 2020Mon Oct 26 19:52:14 2020
    
    33  Thread-1Thread-2  Mon Oct 26 19:52:15 2020Mon Oct 26 19:52:15 2020
    
    44  Thread-2Thread-1  Mon Oct 26 19:52:16 2020Mon Oct 26 19:52:16 2020

    (2)采用锁,先执行线程1,后执行线程2.

    import threading
    from time import sleep,ctime
    
    class MyThread(threading.Thread):
        def __init__(self, func, arg):
            super(MyThread, self).__init__()
            self.func = func
            self.arg = arg
        # 重写run()方法
        def run(self):
            
            threadLock.acquire() #获取锁,用于线程同步
            
            self.func(self.arg)
            
            threadLock.release()#释放锁,开启下一个线程
            
    
    def f(n):
        for i in range(n):
            sleep(1)
            print(i,threading.current_thread().name,ctime())
    
    
    threadLock = threading.Lock()
    
    
    for i in range(2):
        thread = MyThread(f,5)
        thread.start()

    输出如下:

    0 Thread-1 Mon Oct 26 19:59:17 2020
    1 Thread-1 Mon Oct 26 19:59:18 2020
    2 Thread-1 Mon Oct 26 19:59:19 2020
    3 Thread-1 Mon Oct 26 19:59:20 2020
    4 Thread-1 Mon Oct 26 19:59:21 2020
    0 Thread-2 Mon Oct 26 19:59:22 2020
    1 Thread-2 Mon Oct 26 19:59:23 2020
    2 Thread-2 Mon Oct 26 19:59:24 2020
    3 Thread-2 Mon Oct 26 19:59:25 2020
    4 Thread-2 Mon Oct 26 19:59:26 2020

    应用所阻塞子线程的执行,应用join阻塞主线程的执行。

    import threading
    from time import sleep,ctime
    
    class MyThread(threading.Thread):
        def __init__(self, func, arg):
            super(MyThread, self).__init__()
            self.func = func
            self.arg = arg
        # 重写run()方法
        def run(self):
            threadLock.acquire() #获取锁,用于线程同步
            self.func(self.arg)
            threadLock.release()#释放锁,开启下一个线程
            
    number=0
    def f(n):
        global number
        for i in range(n):
            number+=1
        print(number,threading.current_thread().name,ctime())
    
    
    threadLock = threading.Lock()
    
    threads=[]
    for i in range(10):
        thread = MyThread(f,10)
        threads.append(thread)
    
    for t in threads:
        t.start()
        t.join()
    
    
    print(number,threading.current_thread().name,ctime())

    输出如下:

    10 Thread-1 Mon Oct 26 20:09:59 2020
    20 Thread-2 Mon Oct 26 20:09:59 2020
    30 Thread-3 Mon Oct 26 20:09:59 2020
    40 Thread-4 Mon Oct 26 20:09:59 2020
    50 Thread-5 Mon Oct 26 20:09:59 2020
    60 Thread-6 Mon Oct 26 20:09:59 2020
    70 Thread-7 Mon Oct 26 20:09:59 2020
    80 Thread-8 Mon Oct 26 20:09:59 2020
    90 Thread-9 Mon Oct 26 20:09:59 2020
    100 Thread-10 Mon Oct 26 20:09:59 2020
    100 MainThread Mon Oct 26 20:09:59 2020
  • 相关阅读:
    Devexpress GridView添加行号
    Devexpress GridControl 常用设置
    导入Excel部分数据导入不了的原因及处理
    GridView里面的HyperLink和ButtonField操作总结
    sybase数据表的导出与导入
    uniapp的unistarter的白名单访问模式需要绝对路径
    vue 用vif隐藏显示切换大量dom元素,导致一个页面上一个组件多次调用的created不能全部执行的修改方法
    2013腾讯编程马拉松初赛:小Q系列故事——屌丝的逆袭
    Tensorflow Federated(TFF)框架整理(上)
    Stateful TFF
  • 原文地址:https://www.cnblogs.com/yijierui/p/13880785.html
Copyright © 2020-2023  润新知