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
  • 相关阅读:
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目
    Neo4j批量插入(Batch Insertion)
    嵌入式(Embedded)Neo4j数据库访问方法
    Neo4j 查询已经创建的索引与约束
    Neo4j 两种索引Legacy Index与Schema Index区别
    spring data jpa hibernate jpa 三者之间的关系
    maven web project打包为war包,目录结构的变化
    创建一个maven web project
    Linux下部署solrCloud
  • 原文地址:https://www.cnblogs.com/wooya/p/5959276.html
Copyright © 2011-2022 走看看