zoukankan      html  css  js  c++  java
  • 多线程原理

    线程处理IO密集型任务

    import threading
    import time
    def foo(something):
        print(something)
        time.sleep(1)

    begin_time = time.time()
    '''
    #
    总消耗时长: 2.001000165939331
    foo("磁盘写入100M数据")
    foo("cpu去做其他事情")
    '''

    '''
    #总消耗时长: 0.0010004043579101562
    #创建线程实例
    t1 = threading.Thread(target=foo,args=("磁盘写入100M数据",))
    t2 = threading.Thread(target=foo,args=("cpu去做其他事情",))
    #启动线程
    t1.start()
    t2.start()
    '''

    '''
    #总消耗时长:  1.001000165939331
    #创建线程实例
    t1 = threading.Thread(target=foo,args=("磁盘写入100M数据",))
    t2 = threading.Thread(target=foo,args=("cpu去做其他事情",))
    #启动线程
    t1.start()
    t2.start()
    #在子线程完成运行之前,这个子线程的主线程一直被阻塞
    t1.join()
    t2.join()  #可以只有一个join
    '''
    end_time = time.time()
    print("总消耗时长:",end_time-begin_time)

    线程处理计算密集型任务

    import threading
    import time
    def foo():
        num = 0
        for i in range(10000000):
            num = num + i

    begin_time = time.time()
    '''
    #
    串行 总消耗时长:1.819000005722046
    foo()
    foo()
    '''

    '''
    #并发 总消耗时长:1.7979998588562012
    t1 = threading.Thread(target=foo)
    t2 = threading.Thread(target=foo)

    t1.start()
    t2.start()

    t1.join()
    t2.join()
    '''
    end_time = time.time()
    print("总消耗时长:",end_time-begin_time)

    join的功能

     

    输出:

    这是最后一行代码

    3s后

    阳光明媚

    阻塞线程:

    输出:

    阳光明媚

    3s后

    这是最后一行代码

    守护线程

    import threading
    import time

    a = []
    def foo():
        while True:
            a.append("1")
            print("产生了一个数据")
            time.sleep(1)
    t = threading.Thread(target=foo)
    #设置守护线程,必须在start之前
    #作用就是在主线程想要提出进程的时候,不需要等待自己结束,直接退出就行
    t.setDaemon(True)
    t.start()
    for i in range(5):
        if a:
            a.remove("1")
            print("消耗了一个数据")
            time.sleep(1)

    print("不再需要消耗数据了")

    输出:

     

    不安全的开发

    无锁:

    import threading
    import time
    balance = 500 #账户余额
    #操作账户余额
    def foo(num):
        #声明全局变量
       
    global balance
        #把接口获取到的值放进自己的变量系统
       
    user_balance = balance
        time.sleep(1) #防止代码太少,cpu执行速度过快,造成串行
        #计算出结果
       
    user_balance = user_balance + num
        #将结果通过接口传递出去
       
    balance = user_balance
    #消费300元
    t1 = threading.Thread(target=foo,args=[-300])
    #收入10000元
    t2 = threading.Thread(target=foo,args=[10000])
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("账户余额:",balance)   #值不稳定,200或10500随机出现

    上锁:

    import threading
    import time
    balance = 500 #账户余额
    r = threading.Lock()  #声明一把锁
    '''
    这是一把同步锁
    同步锁必须 上锁 解锁 相对
    如果上锁后,不解锁,再次上锁,代码会阻塞
    如果解锁后,不上锁,又进行解锁,代码会报错
    '''
    #操作账户余额
    def foo(num):
        #声明全局变量
       global balance
        #上锁
       
    r.acquire()   
        #把接口获取到的值放进自己的变量系统
       
    user_balance = balance
        time.sleep(1) #防止代码太少,cpu执行速度过快,造成串行
        #计算出结果
       
    user_balance = user_balance + num
        #将结果通过接口传递出去
       
    balance = user_balance
        #解锁
       
    r.release()
    #消费300元
    t1 = threading.Thread(target=foo,args=[-300])
    #收入10000元
    t2 = threading.Thread(target=foo,args=[10000])
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("账户余额:",balance)   #10200

    死锁

    import threading
    import time
    lockA = threading.Lock()   #面试官的锁
    lockB = threading.Lock()   #小明的锁
    #面试官
    def foo1():
        lockA.acquire() #上锁
       
    print("请解释什么是死锁")
        time.sleep(1)
        lockB.acquire()  #上锁
       
    print("发 offer")
        time.sleep(1)
        lockA.release()  #释放锁
       
    lockB.release()  #释放锁
    #小明
    def foo2():
        lockB.acquire()  # 上锁
       
    print("请给我 offer")
        time.sleep(1)
        lockA.acquire()  # 上锁
       
    print("解释了什么是死锁")
        time.sleep(1)
        lockA.release()  # 释放锁
       
    lockB.release()  # 释放锁
    t1 = threading.Thread(target=foo1)
    t2 = threading.Thread(target=foo2)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    输出:

    递归锁

    import threading
    import time
    # lockA = threading.Lock()   #面试官的锁
    # lockB = threading.Lock()   #小明的锁
    lockR = threading.RLock() #递归锁
    '''
    递归锁内部维护着一把锁和一个计算器
    每次上锁:计数器加1
    每次解锁:计数器减1
    计数器可以大于0,也可以等于0,但不能小于0
    '''
    #面试官
    def foo1():
        lockR.acquire() #上锁
       
    print("请解释什么是死锁")
        time.sleep(1)
        lockR.acquire()  #上锁
       
    print("发 offer")
        time.sleep(1)
        lockR.release()  #释放锁
       
    lockR.release()  #释放锁
    #小明
    def foo2():
        lockR.acquire()  # 上锁
       
    print("请给我 offer")
        time.sleep(1)
        lockR.acquire()  # 上锁
       
    print("解释了什么是死锁")
        time.sleep(1)
        lockR.release()  # 释放锁
       
    lockR.release()  # 释放锁
    t1 = threading.Thread(target=foo1)
    t2 = threading.Thread(target=foo2)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    输出:

     

  • 相关阅读:
    linux重新编译内核
    无废话ubuntu 13.4w文件共享配置
    VB6关于判断模态窗体的问题
    在.NET中快速创建一个5GB、10GB或更大的空文件
    利用虚拟光驱实现 将WINDOWS文件供虚拟机中的UBUNTU共享
    论这场云盘大战,以及各网盘的优劣
    struts2 全局格式化,格式化时间,金钱,数字
    SQL SERVER 2000/2005/2008数据库数据迁移到Oracle 10G细述
    女攻城师走在移动互联网道路的这两年
    用正则匹配多行文本
  • 原文地址:https://www.cnblogs.com/like1824/p/12891214.html
Copyright © 2011-2022 走看看