• 多线程学习总结


     

    一 起线程

    以函数的方式以一个线程

    import threading
    import time
    
    def run(n):
        print("task ", n)
        time.sleep(2)
        print("task done", n)
    
    start_time = time.time()
    t_objs = []  # 存线程实例
    for i in range(10):
        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...")
    print("cost:", time.time() - start_time)

    测试时间略大于2秒. 主线程和这个主线程所启动的子线程是并行的,主线程的执行和子线程无关,要想在程序中让主线程等待子线程 的执行,只能加join() 方法.

     二 以类的方式起线程

    import threading
    import time
    
    
    class MyThread(threading.Thread):
        def __init__(self, n, sleep_time):
            super(MyThread, self).__init__()
            self.n = n
            self.sleep_time = sleep_time
    
        def run(self):
            # 重写父类的run 函数,所以只能是这个函数名
            print("runnint task ", self.n)
            time.sleep(self.sleep_time)
            print("task done,", self.n)
    
    t1 = MyThread("t1", 2)
    t2 = MyThread("t2", 4)
    
    t1.start()
    t2.start()
    
    t1.join()
    t2.join()
    # 写上这两句之后,先把t1和t2执行完之后再执行print("main thread...."),不然就是先执行print("main thread....")

    二 守护线程

    import threading
    import time
    
    def run(n):
        print("task ",n )
        time.sleep(5)
        print("task done",n,threading.current_thread())
    
    start_time = time.time()
    t_objs = [] #存线程实例
    for i in range(5):
        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()
    
    time.sleep(1)
    print("----------all threads has finished...",threading.current_thread(),threading.active_count())
    print("cost:",time.time() - start_time)

    如果没有设置守护线程,

    可以看出,是先把print 语句执行完之后,程序再等待执行所有子线程执行完的, 

    加上守护线程之后的结果

    程序没有等待子线程执行完之后就退出了.  

    把join() 加上之后(也就是把那两行代码的注释取消之后)的结果:

      这里主要是比较他们执行的顺序.

     三 线程锁

    import threading
    import time
    
    
    def run(n):
        lock.acquire()  # 加锁,
        global num
        num += 1
        time.sleep(0.2)
        lock.release()  # 解锁
    
    lock = threading.Lock()  # 生成一个线程锁实例
    num = 0
    t_objs = []  # 存线程实例
    for i in range(5):
        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:", num)

    加锁之后,在锁中间部分程序就是串行了,Python3中解释器自动加锁了,所以可以不再加锁,

    四 递归锁

    import threading, time
    
    
    def run1():
        print("grab the first part data")
        lock.acquire()
        global num
        num += 1
        lock.release()
        return num
    
    def run2():
        print("grab the second part data")
        lock.acquire()
        global num2
        num2 += 1
        lock.release()
        return num2
    
    def run3():
        lock.acquire()
        res = run1() #这里执行run1,而run1中已有锁,所以需要递归锁,使用和平常锁一样,只是在声明时声明为递归锁就行
        print('--------between run1 and run2-----')
        res2 = run2()
        lock.release()
        print(res, res2)
    
    num, num2 = 0, 0
    lock = threading.RLock() #声明为递归锁
    for i in range(1):
        t = threading.Thread(target=run3)
        t.start()
    
    while threading.active_count() != 1:
        print(threading.active_count())
    else:
        print('----all threads done---')
        print(num, num2)

    递归锁和线程锁用法是一样的,只是需要在声明时声明成递归锁就行

    五 信号量

    import threading, 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(22):
            t = threading.Thread(target=run, args=(i,))
            t.start()
    while threading.active_count() != 1:
        pass  # print threading.active_count()
    else:
        print('----all threads done---')
        # print(num)
    
        # 信息号和线程锁用法一样,只是在声明时声明一个信息号就行

    信息号和线程锁用法一样,只是在声明时声明一个信号量就行

    六 事件Event

    import time
    import threading
    
    
    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] sees 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()

    事件程序只有三种状态,set(), wait(),clear(),可以在这三种状态下分别做事情,

    七 线程队列

    # 生产者 消费者模型
    import threading,time
    
    import queue
    
    q = queue.Queue(maxsize=10)  # 定义一个共用的线程queue
    
    def Producer(name):
        count = 1
        while True:
            q.put("包子%s" % count)
            print("生产了包子",count)
            count +=1
            time.sleep(0.5)
    
    def Consumer(name):
        #while q.qsize()>0:
        while True:
            print("[%s] 取到[%s] 并且吃了它..." %(name, q.get()))
            time.sleep(1)
    
    p = threading.Thread(target=Producer,args=("zhangsan",))
    c = threading.Thread(target=Consumer,args=("lishi",))
    c1 = threading.Thread(target=Consumer,args=("wangwu",))
    
    p.start()
    c.start()
    c1.start()
  • 相关阅读:
    Ogre参考手册(九) 5 硬件缓冲区
    Ogre参考手册(十二) 8 动画
    Ogre参考手册(三)3.1.3 纹理单元TextureUnit
    在Ogre中直接使用D3D
    Ogre参考手册(四)3.1.43.1.14 声明顶点、几何、片段程序(Ogre着色器脚本)
    制作立体图像(上):红蓝眼镜原理
    算法学习(java实现)
    JAVA 的data类型 long类型 生成星期几汇总
    Android R.java解析
    Myeclipse的使用方法查找类文件(Open Type)
  • 原文地址:https://www.cnblogs.com/liuqianli/p/8400651.html
Copyright © 2020-2023  润新知