zoukankan      html  css  js  c++  java
  • python成长之路【第十一篇】:网络编程之线程threading模块

    一、threading模块介绍

    threading 模块建立在 _thread 模块之上。thread 模块以低级、原始的方式来处理和控制线程,而 threading 模块通过对 thread 进行二次封装,提供了更方便的 api 来处理线程。

    示例:

    import threading
    import time
    
    def process(arg):
        time.sleep(1)
        print(arg)
    
    # 普通方式
    # for i in range(10):
    #     process(i)
    
    # 多线程方式,创建了10个线程
    for i in range(10):
        t = threading.Thread(target=process, args=(i,))
        t.start()
    View Code
    thread方法说明:
    	t.start() : 激活线程
    	t.getName() : 获取线程的名称
    	t.setName() : 设置线程的名称 
    	t.name : 获取或设置线程的名称
    	t.is_alive() : 判断线程是否为激活状态
    	t.isAlive() :判断线程是否为激活状态
    	t.setDaemon() 设置为后台线程或前台线程(默认:False);通过一个布尔值设置线程是否为守护线程,必须在执行start()方法之后才可以使用。如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止;如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
    	t.isDaemon() : 判断是否为守护线程
    	t.ident :获取线程的标识符。线程标识符是一个非零整数,只有在调用了start()方法之后该属性才有效,否则它只返回None。
    	t.join() :逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
    	t.run() :线程被cpu调度后自动执行线程对象的run方法
    

    示例2:使用类的方式

    import threading
    
    class MyThread(threading.Thread):
        def __init__(self, n):
            super(MyThread, self).__init__()
            self.n = n
        def run(self):
            print("running task ", self.n)
    
    t1 = MyThread("t1")
    t2 = MyThread("t2")
    t1.start()
    t2.start()
    View Code

    二、线程锁threading.RLock和threading.Lock

    我们使用线程对数据进行操作的时候,如果多个线程同时修改某个数据,可能会出现不可预料的结果,为了保证数据的准确性,引入了锁的概念。

    示例:

    # 锁lock,为了实现各个线程协同修改num。
    import threading
    import time
    num = 0
    lock = threading.Lock()
    
    def run(n):
        lock.acquire()  #获得锁
        global num
        num += 1
        # time.sleep(1)
        lock.release()  #释放锁
    
    t_objs = []  #存放线程实例
    for i in range(50):
        t = threading.Thread(target=run, args=("t-%s" %i,))
        t.start()
        t_objs.append(t)  #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里
    
    for t in t_objs:  #循环线程实例列表,等待所有线程执行完毕
        t.join()
    
    print("------all threads has finished...",threading.current_thread(),threading.active_count())
    print("num %s" % num)
    View Code

    threading.RLock和threading.Lock 的区别

    RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况。 如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐。

        import threading
        lock = threading.Lock()    #Lock对象
        lock.acquire()
        lock.acquire()  #产生了死琐。
        lock.release()
        lock.release()
        
        import threading
        rLock = threading.RLock()  #RLock对象
        rLock.acquire()
        rLock.acquire()    #在同一线程内,程序不会堵塞。
        rLock.release()
        rLock.release()
    View Code

    三、threading.Event

    Event是线程间通信最间的机制之一:一个线程发送一个event信号,其他的线程则等待这个信号。用于主线程控制其他线程的执行。 Events 管理一个flag,这个flag可以使用set()设置成True或者使用clear()重置为False,wait()则用于阻塞,在flag为True之前。flag默认为False。

    	Event.wait([timeout]) : 堵塞线程,直到Event对象内部标识位被设为True或超时(如果提供了参数timeout)。
    	Event.set() :将标识位设为Ture
    	Event.clear() : 将标识位设为False。
    	Event.isSet() :判断标识位是否为Ture。
    

    当线程执行的时候,如果flag为False,则线程会阻塞,当flag为True的时候,线程不会阻塞。它提供了本地和远程的并发性。

    示例:# 实现红灯停,绿灯行

    import threading
    import time
    
    event = threading.Event()
    
    def lighter():
        count = 0
        event.set()  #先设置绿灯
        while True:
            if count > 5 and count < 10:  #改成红灯
                event.clear()  #把标志位清了
                print("33[41;1mred light is on...33[0m")
            elif count > 10:
                event.set()  #变绿灯
                count = 0
            else:
                print("33[42;1mgreen light is on...33[0m")
            time.sleep(1)
            count += 1
    
    def car(name):
        while True:
            if event.is_set():  #代表绿灯
                print("[%s] running..."% name)
                time.sleep(1)
            else:
                print("[%s] see red light,waiting..." % name)
                event.wait()
                print("33[34;1m[%s] green light is on, start going...33[0m" % name)
    
    light = threading.Thread(target=lighter,)
    light.start()
    
    car1 = threading.Thread(target=car,args=("Tesla",))
    car1.start()
    car2 = threading.Thread(target=car,args=("BMW",))
    car2.start()
    View Code

    四、semaphore信号量

    示例:

    import threading
    import time
    
    def run(n):
        semaphore.acquire()
        time.sleep(1)
        print("run the thread: %s
    " % n)
        semaphore.release()
    
    if __name__ == '__main__':
        semaphore = threading.BoundedSemaphore(5)  # 最多允许5个线程同时运行
        for i in range(20):
            t = threading.Thread(target=run, args=(i,))
            t.start()
    
    while threading.active_count() != 1:
        pass  # print threading.active_count()
    else:
        print('----all threads done---')
    View Code

    五、设置子线程

    示例:

    import threading
    import time
    def run(n):
        print("task ", n)
        time.sleep(2)
        print("task done",n,threading.current_thread())
    
    start_time = time.time()
    t_objs = []  #存放线程实例
    for i in range(50):
        t = threading.Thread(target=run, args=("t-%s" %i,))
        t.setDaemon(True)  #把当前线程设置为守护线程
        t.start()
        t_objs.append(t)  #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里
    
    # for t in t_objs:
    #     t.join()
    
    print("------all threads has finished...",threading.current_thread(),threading.active_count())
    print("cost:",time.time() - start_time)
    View Code
  • 相关阅读:
    canvas制作倒计时炫丽效果
    MySQL存储过程
    SpringMVC入门
    JAVA面试/笔试经典题
    JAVA内存存储分配粗略讲解
    数据结构算法总结
    稳定排序
    Java集合框架
    Java笔试题及答案
    面向接口
  • 原文地址:https://www.cnblogs.com/wooya/p/5959276.html
Copyright © 2011-2022 走看看