• 死锁现象与解决方案,开启线程的2种方式,守护线程,线程VS进程,线程互斥锁,信号量


    死锁现象与解决方案

    from threading import Thread,Lock,active_count
    import time
    
    mutexA=Lock() # 锁1
    mutexB=Lock() # 锁2
    
    
    class Mythread(Thread):
        def run(self):
            self.f1()
            self.f2()
    
        def f1(self):
            mutexA.acquire()
            print('%s 拿到A锁' %self.name)
    
            mutexB.acquire()
            print('%s 拿到B锁' %self.name)
            mutexB.release()
    
            mutexA.release()
    
        def f2(self):
            mutexB.acquire()
            print('%s 拿到B锁' %self.name)
            time.sleep(1)
    
            mutexA.acquire()
            print('%s 拿到A锁' %self.name)
            mutexA.release()
    
            mutexB.release()
    
    if __name__ == '__main__':
        for i in range(10):
            t=Mythread()
            t.start()
        # print(active_count())
    #死锁现象: 线程1拿到一把锁,线程2也拿到一把锁,线程1想要线程2的锁,线程2想要线程1的锁,于是就阻塞了,这说明 2把锁不能同时acquire   
    # 解决方法如下,递归锁
    from threading import Thread,Lock,active_count,RLock
    import time
    
    # mutexA=Lock()
    # mutexB=Lock()
    obj=RLock() #递归锁的特点:可以连续的acquire.其本质其实还是一把锁,只是把一把锁转换成了2把而已
    mutexA=obj
    mutexB=obj
    
    class Mythread(Thread):
        def run(self):
            self.f1()
            self.f2()
    
        def f1(self):
            mutexA.acquire()
            print('%s 拿到A锁' %self.name)
    
            mutexB.acquire()
            print('%s 拿到B锁' %self.name)
            mutexB.release()
    
            mutexA.release()
    
        def f2(self):
            mutexB.acquire()
            print('%s 拿到B锁' %self.name)
            time.sleep(1)
    
            mutexA.acquire()
            print('%s 拿到A锁' %self.name)
            mutexA.release()
    
            mutexB.release()
    
    if __name__ == '__main__':
        for i in range(10):
            t=Mythread()
            t.start()
        # print(active_count())
    死锁现象与递归锁解决方案

    开启线程的2种方式

    from threading import Thread
    import time
    
    #方式一
    def task(name):
        print('%s is running' %name)
        time.sleep(3)
        print('%s is done' %name)
    if __name__ == '__main__':
        t=Thread(target=task,args=('子线程',))
        t.start()
        print('')
    #开启并发线程比开启并发进程要快的多,线程是在进程里开启,而进程是向操作系统发请求开辟一个新的内存空间
    
    
    #方式二
    # class Mythread(Thread):
    #     def run(self):
    #         print('%s is running' %self.name)
    #         time.sleep(3)
    #         print('%s is done' %self.name)
    #
    # if __name__ == '__main__':
    #     t=Mythread()
    #     t.start()
    #     print('主')
    开启线程的2种方式
    01 什么是线程
        进程其实不是一个执行单位,进程是一个资源单位
        每个进程内自带一个线程,线程才是cpu上的执行单位
    
        如果把操作系统比喻为一座工厂
            在工厂内每造出一个车间===》启动一个进程
            每个车间内至少有一条流水线===》每个进程内至少有一个线程
    
        线程=》单指代码的执行过程
        进程-》资源的申请与销毁的过程
    
    02 进程vs线程
        1、 内存共享or隔离
            多个进程内存空间彼此隔离
            同一进程下的多个线程共享该进程内的数据
    
        2、创建速度
            造线程的速度要远远快于造进程
    # 主进程等子进程是因为主进程要给子进程收尸
    # 进程必须等待其内部所有线程都运行完毕才结束
    # from threading import Thread
    # import time
    #
    # def task(name):
    #     print('%s is running' %name)
    #     time.sleep(3)
    #     print('%s is done' %name)
    # if __name__ == '__main__':
    #     t=Thread(target=task,args=('子线程',))
    #     t.start()
    #     print('主')
    #
    
    
    from threading import Thread,current_thread,active_count,enumerate
    import time
    
    
    def task():
        print('%s is running' % current_thread().name)
        time.sleep(3)
        print('%s is done' % current_thread().name)
    
    
    if __name__ == '__main__':
        t = Thread(target=task,name='xxx')
        t.start()
        # t.join()
        # print(t.is_alive())
        # print(t.getName())
        # print(t.name)
        # print('主',active_count())
        # print(enumerate())
    
        # t.join()
        current_thread().setName('主线程')
        print('',current_thread().name)
    线程对象的其他属性与方法

    守护线程

    # 守护线程会在本进程内所有非守护的线程都死掉了才跟着死
    # 即:
    # 守护线程其实守护的是整个进程的运行周期(进程内所有的非守护线程都运行完毕)
    # from threading import Thread,current_thread
    # import time
    #
    #
    # def task():
    #     print('%s is running' % current_thread().name)
    #     time.sleep(3)
    #     print('%s is done' % current_thread().name)
    #
    #
    # if __name__ == '__main__':
    #     t = Thread(target=task,name='守护线程')
    #     t.daemon=True
    #     t.start()
    #     print('主')
    
    
    from threading import Thread
    import time
    def foo():
        print(123)
        time.sleep(3)
        print("end123")
    
    def bar():
        print(456)
        time.sleep(1)
        print("end456")
    
    
    t1=Thread(target=foo)
    t2=Thread(target=bar)
    
    t1.daemon=True
    t1.start()
    t2.start()
    print("main-------")
    
    '''
    123
    456
    main-------
    end456
    
    '''
    守护线程

    线程VS进程

    #1、线程的开启速度快
    # from threading import Thread
    # from multiprocessing import Process
    # import time
    #
    # def task(name):
    #     print('%s is running' %name)
    #     time.sleep(3)
    #     print('%s is done' %name)
    #
    # if __name__ == '__main__':
    #     t=Thread(target=task,args=('子线程',))
    #     # t=Process(target=task,args=('子进程',))
    #     t.start()
    #     print('主')
    
    
    #2、同一进程下的多个线程共享该进程内的数据
    # from threading import Thread
    # import time
    #
    # x=100
    # def task():
    #     global x
    #     x=0
    #
    # if __name__ == '__main__':
    #     t=Thread(target=task,)
    #     t.start()
    #     # time.sleep(3)
    #     t.join()
    #     print('主',x)
    
    
    # 查看pid
    from threading import Thread
    import time,os
    
    def task():
        print(os.getpid())
    
    if __name__ == '__main__':
        t=Thread(target=task,)
        t.start()
        print('',os.getpid())
    线程vs进程

    线程互斥锁

    from threading import Thread,Lock
    import time
    
    mutex=Lock()
    
    x=100
    def task():
        global x
        # mutex.acquire()
        temp=x
        time.sleep(0.1)
        x=temp-1
        # mutex.release()
    
    if __name__ == '__main__':
        t_l=[]
        start=time.time()
        for i in range(100):
            t=Thread(target=task)
            t_l.append(t)
            t.start()
    
        for t in t_l:
            t.join()
    
        stop=time.time()
        print(x,stop-start) 
        # 打印结果为  99 0.1123046875
        # 这说明同一进程下的线程数据是共享的
    View Code

    信号量

    信号量:限制的是同一进程下并发执行的任务数(其本质也是锁,同一时间可以运行多个任务)
    而互斥锁同一时间只能运行一个任务
    # 信号量是控制同一时刻并发执行的任务数
    from threading import Thread,Semaphore,current_thread
    import time,random
    
    sm=Semaphore(5)  # 控制同一个时刻并发运行的多个任务个数
    
    def task():
        with sm:  # with sm   其意思是:sm.acquire() (上锁)        sm.release()(解锁)
            print('%s 正在上厕所' %current_thread().name)
            time.sleep(random.randint(1,4))
    
    
    if __name__ == '__main__':
        for i in range(20):
            t=Thread(target=task)
            t.start()
    View Code
  • 相关阅读:
    RMQ
    LCA 笔记
    LUCAS 定理
    topcoder 643 DIV2
    BZOJ 1071组队
    Codeforces Round #283 (Div. 2)
    topcoder 642
    Codeforces Round #278 (Div. 2)
    树链剖分
    Codeforces Round #277 (Div. 2)
  • 原文地址:https://www.cnblogs.com/xiejintao0914/p/9314004.html
Copyright © 2020-2023  润新知