• Python多线程


     

    Python多线程的使用及其相关概念介绍

    异步与多线程的区别:https://www.cnblogs.com/dream844/archive/2012/06/12/2546083.html

    1. 线程的基本使用

      1.1 直接通过threading模块注册使用

    # -*- coding:utf-8 -*-
    # Author:Wong Du
    
    '''
    多线程的简单使用
    '''
    import threading
    import time
    
    def war(n):
        for i in range(10):
            print("task ", n, i)
        time.sleep(2)
    
    # 注册线程
    t1 = threading.Thread(target=war, args=("t1",))
    t2 = threading.Thread(target=war, args=("t2",))
    
    # 运行线程
    t1.start()
    t2.start()
    
    # war("t1")
    # war("t2")

      1.2 通过继承threading.Thead类,重写run函数方法来调用线程

    # -*- coding:utf-8 -*-
    # Author:Wong Du
    
    import threading
    import time
    
    class MyThreading(threading.Thread):
        def __init__(self, n, sleep_time):
            super(MyThreading, self).__init__()
            self.n = n
            self.sleep_time = sleep_time
    
        def run(self):
            print("Task ", self.n)
            time.sleep(self.sleep_time)
    
    # 注册线程
    t1 = MyThreading("t1", 2)
    t2 = MyThreading("t2", 4)
    
    # 运行线程
    t1.start()
    t2.start()
    
    # 等待t1线程执行完才执行后续代码
    t1.join()
    print("Task t1 is done...")

      1.3 多线程并行执行

     1 # -*- coding:utf-8 -*-
     2 # Author:Wong Du
     3 
     4 import threading
     5 import time
     6 
     7 # 定义一个函数任务,作为注册线程使用
     8 def war(n):
     9     print("task", n)
    10     time.sleep(2)
    11 
    12 # 注册的线程列表
    13 t_list = []
    14 # 程序开始启动线程时间
    15 start_time = time.time()
    16 # 运行多个线程
    17 for i in range(50):
    18     t = threading.Thread(target=war, args=("t-%s" % i,))
    19     t.start()
    20     # 把注册的线程加到列表里
    21     t_list.append(t)
    22 
    23 # join一下,等待所有线程执行完毕
    24 for t in t_list:
    25     t.join()
    26 
    27 # 计算同时开启50个线程执行完毕花费的时间
    28 print("33[32;1mSpeed time is %s33[0m" % (time.time() - start_time))
    多线程并行执行时间开销计算

    2. 子线程和守护线程

      子线程:Python多线程的子线程和主线程相对独立,内存共享

      守护线程:通过setDaemon(True)可将线程设置成守护线程,守护线程为非守护线程服务,当非守护线程都执行完毕时,无论守护线程是否执行完毕,都将被强制结束

    # -*- coding:utf-8 -*-
    # Author:Wong Du
    
    '''
    子线程:Python多线程的子线程和主线程相对独立,内存共享
    守护线程:通过setDaemon(True)可将线程设置成守护线程,守护线程为非守护线程服务
              当非守护线程都执行完毕时,无论守护线程是否执行完毕,都将被强制结束
    '''
    
    import threading
    import time
    
    def war(n):
        print("task", n)
        # 由主线程申请调用出来的子线程
        print("I am not main threading...".center(50, '-'), threading.currentThread())
        time.sleep(2)
        print("%s 子线程执行完毕..." % threading.currentThread())
    
    start_time = time.time()
    for i in range(50):
        t = threading.Thread(target=war, args=("t-%s" % i,))
        # 将t线程设置为守护进程
        t.setDaemon(True)
        t.start()
        # 查看当前线程信息
        print("%s is started..." % threading.currentThread())
    
    # 查看当前线程信息及当前程序活跃的线程
    print("I am main threading...".center(50, '-'), threading.currentThread(), threading.active_count())
    print("33[32;1mSpeed time is %s33[0m" % (time.time() - start_time))

    3. Python线程锁和递归锁

    # -*- coding:utf-8 -*-
    # Author:Wong Du
    
    import threading
    import time
    """
    python 2.x中,会出现运算数据不正常的现象,可以通过自己加lock解决
    python 3.x中,python内部进行了优化,无需加lock也不会出现异常
    """
    
    def war():
        # 加锁
        lock.acquire()
        global num
        num += 1
        # time.sleep(0.1)
        # 释放锁
        lock.release()
        time.sleep(0.1)
    
    num = 0
    # 定义一把锁,当用锁锁住时,CPU不会进行上下文的切换,直到当前锁内的代码执行完毕
    lock = threading.Lock()
    
    start_time = time.time()
    t_list = []
    for i in range(50):
        t = threading.Thread(target=war)
        t.start()
        t_list.append(t)
    
    for j in t_list:
        j.join()
    
    print("Num:", num)
    print("33[31;1mSpeed time: %s33[0m" % (time.time() - start_time))
    线程锁
    # -*- coding:utf-8 -*-
    # Author:Wong Du
    
    import threading
    import time
    """
    python 2.x中,会出现运算数据不正常的现象,可以通过自己加lock解决
    python 3.x中,python内部进行了优化,无需加lock也不会出现异常
    Python中,为了避免“锁内加锁”而出现锁同名导致的程序无法正常退出问题,
    引入了Rlock(递归锁)的方法来区分多个用户锁
    """
    
    def run1():
        print("num")
        lock.acquire()
        global num
        num += 10
        lock.release()
        return num
    
    def run2():
        print("num2")
        lock.acquire()
        global num2
        num2 += 1
        lock.release()
        return num2
    
    def run3():
        lock.acquire()
        res1 = run1()
        print("Between run1 to run2...")
        res2 = run2()
        lock.release()
        print(res1, res2)
        time.sleep(3)
    
    num, num2 = 0, 0
    # 定义递归锁,当用锁锁住时,CPU不会进行上下文的切换,直到当前锁内的代码执行完毕
    lock = threading.RLock()
    
    for i in range(5):
        t = threading.Thread(target=run3)
        t.start()
    
    # print("Num:", num)
    while threading.active_count() != 1:
        pass
        # print(num, num2)
    else:
        print("Threading is done...")
        print(num, num2)
    线程递归锁

    4. 多线程信号量控制

      Python线程处理中,Semaphore信号量可以控制“同一时间”切换上下文执行线程的数量

    # -*- coding:utf-8 -*-
    # Author:Wong Du
    
    import threading
    import time
    """
    python 2.x中,会出现运算数据不正常的现象,可以通过自己加lock解决
    python 3.x中,python内部进行了优化,无需加lock也不会出现异常
    Python中,为了避免“锁内加锁”而出现锁同名导致的程序无法正常退出问题,
    引入了Rlock(递归锁)的方法来区分多个用户锁
    Python线程处理中,Semaphore信号量可以控制“同一时间”切换上下文执行线程的数量
    """
    
    def war(n):
        semaphore.acquire()
        time.sleep(1)
        print("Threading:", n)
        semaphore.release()
    
    # 定义信号量数,信号量锁住时,相当于"同一时间",只有5个线程进行上下文切换,即“同时”执行
    semaphore = threading.BoundedSemaphore(5)
    
    for i in range(30):
        t = threading.Thread(target=war, args=(i, ))
        t.start()
    信号量

    5. 线程的事件管理

     1 # -*- coding:utf-8 -*-
     2 # Author:Wong Du
     3 
     4 '''
     5 threading事件管理,下面为红绿灯编程实例
     6 '''
     7 import threading
     8 import time
     9 
    10 # 创建一个线程事件
    11 event = threading.Event()
    12 
    13 def light():
    14     count = 0
    15     # 将事件置为set状态
    16     event.set()
    17     while True:
    18         if count > 5 and count < 10:
    19             # 清除事件的set状态
    20             event.clear()
    21             print("33[41;1mNow is red light...33[0m")
    22         elif count > 10:
    23             # 将事件置为set状态
    24             event.set()
    25             # 重置计数
    26             count = 0
    27         else:
    28             print("33[46;1mNow is green light...33[0m")
    29         count += 1
    30         time.sleep(1)
    31 
    32 def car(name):
    33     while True:
    34         # 判断事件当前是否为set状态
    35         if event.is_set():
    36             print("[%s] is running..." % name)
    37             time.sleep(1)
    38         else:
    39             print("[%s] sees red light, waiting..." % name)
    40             # 将事件置为wait状态,该线程卡住,只有当事件状态变为set时,才继续执行后面的代码
    41             event.wait()
    42             print("[%s] sees green light, running..." % name)
    43 
    44 light0 = threading.Thread(target=light)
    45 light0.start()
    46 
    47 car1 = threading.Thread(target=car, args=("car1", ))
    48 car1.start()
    红绿灯实例

  • 相关阅读:
    How To Run Docker in Docker Container [3 Easy Methods]
    design patterns of refactoring guru
    MathJax A JavaScript display engine for mathematics that works in all browsers.
    SoC the root design principle
    Kubernetes plugin for Jenkins
    Inversion of Control
    Python Metaclasses
    JNLP the foundametal of distributed computing of Jenkins
    C# 表达式树Expression
    ML .NET 电影评论情绪分析
  • 原文地址:https://www.cnblogs.com/Caiyundo/p/9487737.html
Copyright © 2020-2023  润新知