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()
    

      

    上班求生存,下班求发展
  • 相关阅读:
    五大常用算法之二:动态规划算法
    五大常用算法之一:分治算法
    c++控制台程序实现定时器
    Oracle sqlplus设置显示格式命令详解
    存储的基本概念谈
    类UNIX操作系统概念
    从源代码到可执行文件
    SQL更改表字段为自增标识
    enum和int、string的转换操作
    SEO技巧汇集
  • 原文地址:https://www.cnblogs.com/ljf520hj/p/14918071.html
Copyright © 2011-2022 走看看