zoukankan      html  css  js  c++  java
  • python多线程

    GIL 全局解释器锁,python底层自带锁,每个线程在执行的过程中都需要先获取GIL,保证同一时刻只有一个线程在运行,目的是解决多线程同时竞争程序中的全局变量而出现的线程安全问题。

    多线程共享数据量大(几百万)的时候,会有数据不安全

    #多线程开发的时候共享全局变量会带来资源竞争效果,也就是数据不安全。
    #如果想安全要引入线程锁
    import threading x=1 def t1(num): global x for i in range(num): x+=1 print('T1............',x) def t2(num): global x for i in range(num): x+=1 print('T2%%%%%%%%%%%%',x) def m(): tt1=threading.Thread(target=t1,args=(1000000,)) tt2=threading.Thread(target=t2, args=(1000000,)) tt1.start() tt2.start()
    #正确值 2000001

     打印结果图 

    多线程操作全局变量,加锁,# 创建互斥锁,默认不上锁,只有一把锁

    是否加等待时间没有关系

    import threading
    import time
    locka=threading.Lock()
    
    x=1
    def t1(num):
        global x
        print("t1",threading.currentThread().name)
        for i in range(num):
            locka.acquire()
            x+=1
            time.sleep(0.01)
            locka.release()
        print('T1............',x)
    def t2(num):
        print("t2", threading.currentThread().name)
        global x
        for i in range(num):
            locka.acquire()
            time.sleep(0.02)
            x += 1
            locka.release()
        print('T2%%%%%%%%%%%%',x)
    def m():
        print("主", threading.currentThread().name)
        tt1=threading.Thread(target=t1,args=(1000,))
        tt2=threading.Thread(target=t2, args=(1000,))
        tt1.start()
        # tt1.join()
        tt2.start()
        # tt2.join()
    
        # print("线程长度",length)
        while True:
            # print("1111111111111") threading.enumerate() 当前的线程
            length = len(threading.enumerate())
            # print("线程长度",length) 最后只有主线程,主线程为1
            if length<=1:
                break
        print("最终的值",x)
    

      打印结果

     多线程操作类属性,加锁,# 创建互斥锁,默认不上锁,只有一把锁。是否加等待时间没有关系

    import threading
    import time
    class A(object):
    
        locka = threading.Lock()
        x = 1
        def __init__(self,num):
            self.num=num
        def t1(self,num):
            print("t1", threading.currentThread().name)
            for i in range(num):
                # self.locka.acquire()
                self.x += 1
                time.sleep(0.01)
                # self.locka.release()
            print('T1............', self.x)
    
        def t2(self,num):
            print("t2", threading.currentThread().name)
            for i in range(num):
                # self.locka.acquire()
                time.sleep(0.02)
                self.x += 1
                # self.locka.release()
            print('T2%%%%%%%%%%%%', self.x)
    
    def m():
        print("主", threading.currentThread().name)
        tt1 = threading.Thread(target=A.t1, args=(A,10000,))
        tt2 = threading.Thread(target=A.t2, args=(A,10000,))
        tt1.start()
        tt1.join()
        tt2.start()
        tt2.join()
    
        # print("线程长度",length)
        while True:
            # print("1111111111111") threading.enumerate() 当前的线程
            length = len(threading.enumerate())
            # print("线程长度",length) 最后只有主线程,主线程为1
            if length <= 1:
                break
        print("最终的值", A.x)
    

      打印结果

    1、启动线程

    import threading
    def test1():
        print("11111111111")
    if __name__ == '__main__':
        t1=threading.Thread(target=test1)
        t1.start()
    

    2、多线程继承

    #多线程继承
    class Mythread(threading.Thread):
        def __init__(self,n):
         #继承父类 super(Mythread, self).__init__() self.n = n def run(self): print("task类方法……", self.n) time.sleep(1) def main():
       #开启3个线程 for i in range(3):
         #实例化自己的类 t=Mythread(i) t.start()

    3、守护线程

    守护线程:设置一个线程为守护线程,就表示你在说这个线程是不重要的,你的主线程在退出的时候,不用等待那些子线程完成

    情况1:#setDaemon(True) 在start前面设置守护线程,True,主线程结束,子线程就结束

    情况2:#i.setDaemon(False) 或 不设置守护线程。主线程结束后,子线程不结束

    #setDaemon(True) 在start前面设置守护线程,True,主线程结束,子线程就结束
    def movie(func):
        for i in range(2):
            print("看电影",func,ctime())
            sleep(1)
    
    def music(func):
        for i in range(2):
            print("听音乐",func,ctime())
            sleep(2)
    
    threadlist=[]
    t1=threading.Thread(target=movie,args=('扫黑风暴',))
    t2=threading.Thread(target=music,args=('碎银几两',))
    threadlist.append(t1)
    threadlist.append(t2)
    
    def main():
        for i in threadlist:
            i.setDaemon(True)
            i.start()
        print("主线程")
    
    if __name__ == '__main__':
        main()
    

      

    #i.setDaemon(False) 或 不设置守护线程。主线程结束后,子线程不结束
    def movie(func):
        for i in range(2):
            print("看电影",func,ctime())
            sleep(1)
    
    def music(func):
        for i in range(2):
            print("听音乐",func,ctime())
            sleep(2)
    
    threadlist=[]
    t1=threading.Thread(target=movie,args=('扫黑风暴',))
    t2=threading.Thread(target=music,args=('碎银几两',))
    threadlist.append(t1)
    threadlist.append(t2)
    
    def main():
        for i in threadlist:
            i.setDaemon(False)
            i.start()
        print("主线程")
    
    if __name__ == '__main__':
        main()

    4、join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。

    def movie(func):
        for i in range(2):
            print("看电影",func,ctime())
            sleep(1)
    
    def music(func):
        for i in range(2):
            print("听音乐",func,ctime())
            sleep(2)
    
    threadlist=[]
    t1=threading.Thread(target=movie,args=('扫黑风暴',))
    t2=threading.Thread(target=music,args=('碎银几两',))
    threadlist.append(t1)
    threadlist.append(t2)
    
    def main():
        for i in threadlist:
            i.setDaemon(True)
            i.start()
        print("主线程start")
        for j in threadlist:
            i.join()
        print("主线程join")
    
    if __name__ == '__main__':
        main()
    

      

    python死锁

    在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源时,就会造成死锁。

    #方法一死锁
    import time
    import threading
    
    locka=threading.Lock()
    lockb=threading.Lock()
    
    def test1():
        locka.acquire()
        print("threadA拿到A锁")
        time.sleep(1)
        lockb.acquire()
        print("threadA拿到B锁")
        locka.release()
        print("threadA释放B锁")
        lockb.release()
        print("threadA释放B锁")
    def test2():
        lockb.acquire()
        print("threadB拿到B锁")
        time.sleep(1)
        locka.acquire()
        print("threadB拿到B锁")
        lockb.release()
        print("threadB释放B锁")
        locka.release()
        print("threadB释放a锁")
    if __name__ == '__main__':
        t1 = threading.Thread(target=test1)
        t2 = threading.Thread(target=test2)
        t1.start()
        t2.start()
    

    #方法二 死锁

    import threading,time
    locka=threading.Lock()
    lockb=threading.Lock()
    #多线程继承死锁
    class Mythreada(threading.Thread):
        def run(self):
            if locka.acquire():
                print(self.name+'获取了A锁')
                time.sleep(1)
                if lockb.acquire():
                    print(self.name + '获取了A锁,又获取B锁')
                    lockb.release()
                    print("释放B锁")
                locka.release()
                print("释放A锁")
    class Mythreadb(threading.Thread):
        def run(self):
            if lockb.acquire():
                print(self.name+'获取了B锁')
                time.sleep(1)
                if locka.acquire():
                    print(self.name + '获取了B锁,又获取A锁')
                    locka.release()
                    print("释放A锁")
                lockb.release()
                print("释放A锁")
    def main():
        ta=Mythreada()
        tb=Mythreadb()
        ta.start()
        tb.start()
    if __name__ == '__main__':
        main()
    

      

    上班求生存,下班求发展
  • 相关阅读:
    <强化学习>无模型下计算给定策略对应的价值函数,Model free Prediction,评估一个给定策略的表现
    <强化学习>马尔可夫决策过程MDP
    <组合数学>排列组合(2)/可重组合,不相邻组合,SJT算法
    <组合数学>排列组合(1)/格路模型,范德蒙德恒等式
    <组合数学>计数/加减乘除计数/加法法则/乘法法则/减法法则
    <组合数学>开门帖
    <组合数学>幻方
    Windows装机必备
    利用Jmeter操作MySQL数据库
    利用Jenkins插件实现多个job并行后再触发job
  • 原文地址:https://www.cnblogs.com/ljf520hj/p/14918071.html
Copyright © 2011-2022 走看看