zoukankan      html  css  js  c++  java
  • 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()
    红绿灯实例

  • 相关阅读:
    [MySQL] 数据库基本概念
    [LeetCode] Number of 1 Bits
    [LeetCode] Maximum Subarray
    [LeetCode] Search Insert Position
    [LeetCode] Remove Duplicates from Sorted List
    [LeetCode] Path Sum III
    [LeetCode] Not Boring Movies
    [LeetCode] Swap Salary
    [LeetCode] Big Countries
    中国银联全渠道系统商户接入 测试指引-银联网关支付产品
  • 原文地址:https://www.cnblogs.com/Caiyundo/p/9487737.html
Copyright © 2011-2022 走看看