zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    打印九九乘法表
    PAT (Basic Level) Practice (中文) 1091 N-自守数 (15分)
    PAT (Basic Level) Practice (中文)1090 危险品装箱 (25分) (单身狗进阶版 使用map+ vector+数组标记)
    PAT (Basic Level) Practice (中文) 1088 三人行 (20分)
    PAT (Basic Level) Practice (中文) 1087 有多少不同的值 (20分)
    PAT (Basic Level) Practice (中文)1086 就不告诉你 (15分)
    PAT (Basic Level) Practice (中文) 1085 PAT单位排行 (25分) (map搜索+set排序+并列进行排行)
    PAT (Basic Level) Practice (中文) 1083 是否存在相等的差 (20分)
    PAT (Basic Level) Practice (中文) 1082 射击比赛 (20分)
    PAT (Basic Level) Practice (中文) 1081 检查密码 (15分)
  • 原文地址:https://www.cnblogs.com/yijierui/p/13880785.html
Copyright © 2011-2022 走看看