zoukankan      html  css  js  c++  java
  • python 线程(创建2种方式,锁,死锁,递归锁,GIL锁,守护进程)

    ###############总结############

    线程创建的2种方式(重点)

    进程:资源分配单位    线程:cpu执行单位(实体)

    线程的创建和销毁的开销特别小

    线程之间资源共享,是同一个进程中的资源共享,会涉及到安全问题,所以需要加锁解决

    :牺牲了效率,保证了数据安全(重点)

    死锁现象:出现在嵌套的时候,双方互相抢对方已经拿到的锁,导致双方互相等待(重点)

    递归锁: 解决了死锁现象(重点)

      rlock 首先本身就是个互斥锁,维护了一个计数器,每次acquire+1,release就-1,当计数器为0的时候,大家才会抢这个锁

    守护线程:

      守护线程:等待所有非守护线程结束才结束

      守护进程: 主进程运行代码结束,守护进程会随之结束

    GIL锁:

      

    运行一个py文件 需要开辟一块内存,内存中有 cpython解释器,py文件代码

     cpython解释器有 编译器和虚拟机 编译器:编译出来后是c语言的字节码

                  经过虚拟机后:变成可执行的二进制文件 到cpu里面执行

    py文件代码到cpython解释器的时候,会经过一个gil锁,这个锁会把文件中的多个线程变成并行处理的方式

    这样的话 一次只能出一个二进制文件导致单核cpu执行,没法做到多线程

    如果做到同时处理多核计算形任务了? 

    使用多进程运用进程运用多核技术,因为每个进程里面都有cpython解释器程序

    一个普通的cpu 一秒可以随便执行500万条mps 也就是5亿条指令
    如果你的程序是I/O型的(一般你的程序都是这个)(input、访问网址网络延迟、打开/关闭文件读写),
    在什么情况下用的到高并发呢(金融计算会用到,人工智能(阿尔法狗),但是一般的业务场景用不到,爬网页,多用户网站、聊天软件、处理文件)
    I/O型的操作很少占用CPU
    ###第一种
    from
    threading import Thread def f1(n): print(n) if __name__ == '__main__': t1=Thread(target=f1,args=(1,)) t1.start() ###第二种 class mythread(Thread): def __init__(self,name): super().__init__() self.name=name def run(self): print('hellow'+self.name) if __name__ == '__main__': t=mythread('alex') t.start() print('主线程结束')

    #####################

    1
    hellowalex
    主线程结束

    ###查看线程的进程id

    import os
    from  threading import Thread
    def f1(n):
        print('1号',os.getpid())
        print('%s号'%n)
    def f2(n):
        print('2号',os.getpid())
        print('%s'%n)
    if __name__ == '__main__':
        t1=Thread(target=f1,args=(1,))
        t2=Thread(target=f2,args=(2,))
        t1.start()
        t2.start()
        print('主进程id',os.getpid())
    ############
    线程ID是一样的

    ###验证线程是数据共享的

    import os
    import time
    from threading import Thread
    num=100
    def f1(n):
        global num
        num=3
        print('子线程num',num)
    if __name__ == '__main__':
        t=Thread(target=f1,args=(1,))
        t.start()
        t.join()#主进程等待子进程运行完才继续执行
        print('主进程的num',num)
    ###################

    子线程num 3
    主进程的num 3

    ###多进程效率对比

    import time
    from threading import Thread
    from multiprocessing import Process
    def f1():
        for i in range(5):
            i=i+i
    if __name__ == '__main__':
        t_s_time=time.time()
        t_list=[]
        # 查看一下20个线程执行20个任务的执行时间
        for i in range(20):
            t=Thread(target=f1,)
            t.start()
            t_list.append(t)
        [tt.join() for tt in t_list]
        t_e_time=time.time()
        t_dif_time=t_e_time-t_s_time
        # print(t_dif_time)
        #查看一个20个进程执行的任务时间
    ##########################################
        p_s_time=time.time()
        p_list=[]
        for i in range(20):
            p=Process(target=f1,)
            p.start()
            p_list.append(p)
        [pp for pp in p_list]
        p_e_time=time.time()
        p_dif_time=p_e_time-p_s_time
        print('线程执行的时间%s'%t_dif_time)
        print('进程执行的时间%s' % p_dif_time)
    ###################
    线程执行的时间0.003000497817993164
    进程执行的时间0.2560145854949951

    ####锁 牺牲了效率,保证了数据安全(重点)

    import time
    from multiprocessing import Process
    from threading import Thread,Lock
    num=100
    def f1(loc):
        loc.acquire()#没加锁的时候 多个程序会抢一个数据 造成数据不安全
        global num
        tmp=num
        tmp-=1
        time.sleep(0.01)#模拟
        num=tmp
        loc.release()
    if __name__ == '__main__':
        t_loc=Lock()
        t_list=[]
        for i in range(10):
            t=Thread(target=f1,args=(t_loc,))
            t.start()
            t_list.append(t)
        [tt.join() for tt in t_list]
        print('主进程',num)
    ##############
    主进程 90

    #####死锁现象 出现在嵌套的时候,双方互相抢对方已经拿到的锁,导致双方互相等待(重点)

    import time
    from threading import Thread,Lock,RLock
    def f1(locA,locB):
        locA.acquire()
        print('f1>>1号抢到了A锁')
        time.sleep(1)
        locB.acquire()
        print('f1>>1号抢到了B锁')
        locB.release()
        locA.release()
    def f2(locA,locB):
        locB.acquire()
        print('f2>>2号抢到了B锁')
        locA.acquire()
        time.sleep(1)
        print('f2>>2号抢到了A锁')
        locA.release()
        locB.release()
    if __name__ == '__main__':
        locA = Lock()
        locB = Lock()
        t1 = Thread(target=f1,args=(locA,locB))
        t2 = Thread(target=f2,args=(locA,locB))
        t1.start()
        t2.start()
    ##################
    f1>>1号抢到了A锁
    f2>>2号抢到了B锁

    递归锁: 解决了死锁现象(重点)

      rlock 首先本身就是个互斥锁,维护了一个计数器,每次acquire+1,release就-1,当计数器为0的时候,大家才会抢这个锁

    import time
    from threading import Thread,Lock,RLock
    def f1(LocA,LocB):
        # time.sleep(1)
        LocA.acquire()
        print('f1>>1号抢到a锁')
        time.sleep(1)
        LocB.acquire()
        print('f1>>1号抢到b锁')
        LocB.release()
        LocA.release()
    def f2(LocA, LocB):
        # time.sleep(1)
        LocB.acquire()
        print('f2>>2号抢到b锁')
        time.sleep(1)
        LocA.acquire()
        print('f2>>2号抢到a锁')
        LocA.release()
        LocB.release()
    if __name__ == '__main__':
        LockA=Lock()
        LockB=Lock()
        LockA=LockB=RLock()#递归锁,维护一个计时器,acquire+1 release-1
        t1=Thread(target=f1,args=(LockA,LockB))
        t2=Thread(target=f2,args=(LockA,LockB))
        t1.start()
        t2.start()
    #######################
    f1>>1号抢到a锁
    f1>>1号抢到b锁
    f2>>2号抢到b锁
    f2>>2号抢到a锁

    守护线程: 等待所有非守护线程结束才结束

    import time
    from threading import Thread
    def f1():
        time.sleep(3)
        print('xxxxxx')
    def f2():
        time.sleep(2)
        print('普通子进程的代码')
    if __name__ == '__main__':
        p=Process(target=f1,)
        p.daemon=True
        # 等待所有非守护线程结束才结束
        p.start()
        
        p2=Process(target=f2,)
        p2.start()
        p2.join()
        print('主进程,结束')
    ####################
    普通子进程的代码
    主进程,结束
    如果把 上面的 f2 改成3s f1改成2s 会打印出xxxx 因为f2执行时间大于f1函数
    不怕大牛比自己牛,就怕大牛比自己更努力
  • 相关阅读:
    Vue(小案例_vue+axios仿手机app)_go实现退回上一个路由
    nyoj 635 Oh, my goddess
    nyoj 587 blockhouses
    nyoj 483 Nightmare
    nyoj 592 spiral grid
    nyoj 927 The partial sum problem
    nyoj 523 亡命逃窜
    nyoj 929 密码宝盒
    nyoj 999 师傅又被妖怪抓走了
    nyoj 293 Sticks
  • 原文地址:https://www.cnblogs.com/zaizai1573/p/10257718.html
Copyright © 2011-2022 走看看