zoukankan      html  css  js  c++  java
  • 多线程threading

    1、Python自带多线程模块 _thread
    _thread.start_new_thread(function, (参数元组)), function结束,线程也结束

    2、第三方模块 threading, 要重写 init 和 run()

    import threading
    class A(threading.Thread):
        def __init__(self, ):
            thread.Thread.__init__(self)    # 一定要有的
    thread1 = A(参数)
    thread1.start()    # 启动线程
    thread1.exit()    # 结束线程
    thread1.isAlive()    # 线程是否活动
    threading.currentThread()    # 返回当前线程变量
    threading.enumerate()    # 返回正在运行的线程列表
    threading.activeCount()    # 或者len(threading.enumerate()) 返回正在运行的线程数
    
    

    3、.join() 代表即使主程序结束,也要执行完开始的线程才退出

    4、强行要求一个线程结束后再执行另一线程,使用线程同步技术

    • 锁同步(锁定和解锁必须成对出现,不然会死锁)
      将一线程中的run()方法用锁定和解锁包围即可
    threading.Lock()    #线程锁对象,在文件开头创建,后面的类中可直接使用
    threading.Lock().acqure()    # 锁定
    threading.Lock().release()    # 解锁
    
    • 条件变量同步
      条件变量 Condition 对象,除了acqure,release 还有 wait, notify, notifyAll(用来唤醒其他阻塞线程)方法
    import threading
    from threading import Condition
     
     
    class A(threading.Thread):
        def __init__(self, condition, num):
            self.condition = condition
            self.num = num
            super().__init__(name="A")
     
        def run(self):
            with self.condition:
                for i in range(self.num):
                    print("A say: %s + %s 等于多少 ?" % (str(i), str(i)))
                    self.condition.notify()
                    self.condition.wait()
     
     
    class B(threading.Thread):
        def __init__(self, condition, num):
            self.condition = condition
            self.num = num
            super().__init__(name="B")
     
        def run(self):
            self.condition.acquire() # 必须先获得锁才可以调用wait或者notify
            # with self.condition:  # 这里没有使用with,其实如果不使用with你就手动加锁,然后释放。使用with就帮你自动完成,这就和 with open()自动关闭文件流式一样的。
            for i in range(self.num):
                self.condition.wait()
                print("B say: %s + %s 等于 %s." % (str(i), str(i), str(i+i)))
                self.condition.notify()
            self.condition.release()
     
    if __name__ == '__main__':
        condition = Condition()
        a = A(condition, 5)
        b = B(condition, 5)
     
        """
        这里要注意,虽然是a先说话,但是要先启动b,使用了condition的话线程的启动顺序很重要。如果先启动a,那么就会一直卡住。为什么?
        先启动a,那么就会先执行notify,而b还没有启动也就意味着没有wait,所以卡住了,也就是说notify的前提是先有wait才可以。换句话
        说就是你要通知就得先有人在等,在没人等的情况下你通知了这样你就无法获得回复所以就一直卡在那里。所以先启动b就是先等待,然后启动a
        a说完话就通知,这样b可以收到然后处理,然后b回复,之后唤醒a,这样相继执行。
        其实Condition和event是类似的可以理解为基于事件的通知机制。
     
        注意事项: 1. 先调用 with self.condition 或者是 acquire() 也就是先加锁才可以使用wait和notify
                 2. 如果手动加锁之后要手动释放
                 3. 线程启动顺序很重要
        """
        b.start()
        a.start()
    

  • 相关阅读:
    深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则
    深入浅出 Java Concurrency (3): 原子操作 part 2
    深入浅出 Java Concurrency (2): 原子操作 part 1
    深入浅出 Java Concurrency (1) : J.U.C的整体认识
    java中关键字volatile的作用
    教你如何迅速秒杀掉:99%的海量数据处理面试题(转)
    STL容器介绍(转)
    IoC框架
    LeetCode 548. Split Array with Equal Sum (分割数组使得子数组的和都相同)$
    LeetCode 533. Lonely Pixel II (孤独的像素之二) $
  • 原文地址:https://www.cnblogs.com/wolun666/p/14663107.html
Copyright © 2011-2022 走看看