python高级编程——锁

系统 1452 0

 锁

          在使用用的过程中需要导入threading模块的Lock类

 使用锁:

  当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制
  线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互 斥锁。 
  互斥锁为资源引入一个状态:锁定/非锁定。
 

锁的语法

  创建锁、锁定锁、释放锁

            
              from
            
             threading 
            
              import
            
            
               Lock


            
            
              #
            
            
               创建锁
            
            
mutex =
            
               Lock()

            
            
              #
            
            
               获取锁(上锁)
            
            
              mutex.acquire()

            
            
              #
            
            
               释放锁(解锁)
            
            
mutex.release()
          

  在锁定锁的过程中acquire()方法可以接受一个blocking参数,

    如果设定blocking为True,则当前线程会堵塞,直到获取到这个锁为止(如果没有 指定,那么默认为True) 

    如果设定blocking为False,则当前线程不会堵塞

 

  上锁和解锁的过程(假设是多线程调度):

    这个锁一般是为共享资源服务的,即多个线程同时使用共享资源。这个锁同一时间只能有一个线程调度,其他线程阻塞,只有当前调度的线程释放这个锁,阻塞的线程才能调度。

  锁的优点:

    确保了某段关键代码只能有一个线程从头到尾完整的执行。

  锁的缺点:

    组织了多线程的并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大的降低了;代码中可能存在多个锁,如果多个线程拥有多个锁,容易造成死锁。

  死锁的现象(实例):

            
              #
            
            
               死锁 两者都没有释放对方需要的锁,而释放的条件恰好是获取对方释放所需要的锁
            
            
              
#
            
            
               线程1
            
            
              class
            
            
               MyThread1(threading.Thread):
    
            
            
              def
            
            
              __init__
            
            
              (self):
        super().
            
            
              __init__
            
            
              ()

    
            
            
              def
            
            
               run(self):
        
            
            
              #
            
            
               线程1获取A锁
            
            
              if
            
            
               mutexA.acquire():
            
            
            
              print
            
            (self.name+
            
              "
            
            
              -----do1---up-----
            
            
              "
            
            
              )
            sleep(
            
            1
            
              )
            
            
            
              #
            
            
               此时线程2获取了B锁,需要等待线程2释放B锁
            
            
              if
            
            
               mutexB.acquire():
                
            
            
              print
            
            (self.name + 
            
              "
            
            
              -----do1---down-----
            
            
              "
            
            
              )
                mutexB.release()
            mutexA.release()


            
            
              #
            
            
               线程2
            
            
              class
            
            
               MyThread2(threading.Thread):
    
            
            
              def
            
            
              __init__
            
            
              (self):
        super().
            
            
              __init__
            
            
              ()

    
            
            
              def
            
            
               run(self):
        
            
            
              #
            
            
               线程2获取B锁
            
            
              if
            
            
               mutexB.acquire():
            
            
            
              print
            
            (self.name + 
            
              "
            
            
              -----do2---up-----
            
            
              "
            
            
              )
            sleep(
            
            1
            
              )
            
            
            
              #
            
            
               此时线程1获取了A锁,需要等待线程1释放A锁
            
            
              if
            
            
               mutexA.acquire():
                
            
            
              print
            
            (self.name + 
            
              "
            
            
              -----do2---down-----
            
            
              "
            
            
              )
                mutexA.release()
            mutexB.release()


mutexA 
            
            =
            
               threading.Lock()
mutexB 
            
            =
            
               threading.Lock()



            
            
              if
            
            
              __name__
            
             == 
            
              '
            
            
              __main__
            
            
              '
            
            
              :
    
            
            
              #
            
            
               线程1和线程2同时执行
            
            
    t1 =
            
               MyThread1()
    t2 
            
            =
            
               MyThread2()
    t1.start()
    t2.start()    
            
          

  避免死锁的方法:银行家算法

多进程与多线程比较及选择

 是否采用多任务处理,取决于我们的任务类型

 如果是计算密集型,需要大量的CPU资源进行运算,代码的运行效率至关重 要,这样的任务一般不使用多线程进行,因为频繁的任务调度会拖慢CPU的
运算。

 如果是IO密集型,涉及到硬盘读写,网络读写等的任务,更多的时间在等待 IO操作完成,这一类任务可以放到多线程或多进程中来进行。

单线程、多线程、多进程(一起实现同一代码的时间)

            
              #
            
            
               单线程、多线程、多进程的使用及不同
            
            
              
#
            
            
               简单的求和
            
            
              def
            
            
               fib(x):
    res 
            
            =
            
               0
    
            
            
              for
            
             i 
            
              in
            
             range(100000000
            
              ):
        res 
            
            += i*
            
              x
    
            
            
              return
            
            
               res



            
            
              #
            
            
               阶乘
            
            
              def
            
            
               fac(x):
    
            
            
              if
            
             x < 2
            
              :
        
            
            
              return
            
             1
    
            
              return
            
             x*fac(x-1
            
              )



            
            
              #
            
            
               简单的求和
            
            
              def
            
            
               sum(x):
    res 
            
            =
            
               0
    
            
            
              for
            
             i 
            
              in
            
             range(50000000
            
              ):
        res 
            
            += i*
            
              x
    
            
            
              return
            
            
               res



            
            
              #
            
            
               函数列表
            
            
funcs =
            
               [fib, fac, sum]
n 
            
            = 100



            
              class
            
            
               MyThread(threading.Thread):
    
            
            
              def
            
            
              __init__
            
            (self, func, args, name=
            
              ""
            
            
              ):
        super().
            
            
              __init__
            
            
              ()
        self.name 
            
            =
            
               name
        self.func 
            
            =
            
               func
        self.args 
            
            =
            
               args
        self.res 
            
            =
            
               0

    
            
            
              def
            
            
               getResult(self):
        
            
            
              return
            
            
               self.res

    
            
            
              def
            
            
               run(self):
        
            
            
              print
            
            (
            
              "
            
            
              starting 
            
            
              "
            
            , self.name, 
            
              "
            
            
               at: 
            
            
              "
            
            
              , ctime())
        self.res 
            
            =
            
               self.func(self.args)
        
            
            
              print
            
            (self.name, 
            
              "
            
            
              finished at: 
            
            
              "
            
            
              , ctime())



            
            
              def
            
            
               main():
    nfuncs 
            
            =
            
               range(len(funcs))

    
            
            
              print
            
            (
            
              "
            
            
              单线程
            
            
              "
            
            .center(30, 
            
              "
            
            
              *
            
            
              "
            
            
              ))
    start 
            
            =
            
               time()
    
            
            
              for
            
             i 
            
              in
            
            
               nfuncs:
        
            
            
              print
            
            (
            
              "
            
            
              start {} at: {}
            
            
              "
            
            .format(funcs[i].
            
              __name__
            
            
              , ctime()))
        start_task 
            
            =
            
               time()
        
            
            
              print
            
            
              (funcs[i](n))
        end_task 
            
            =
            
               time()
        
            
            
              print
            
            (
            
              "
            
            
              任务 耗时:
            
            
              "
            
            , end_task-
            
              start_task)
        
            
            
              print
            
            (
            
              "
            
            
              {} finished at: {}
            
            
              "
            
            .format(funcs[i].
            
              __name__
            
            
              , ctime()))

    end 
            
            =
            
               time()
    
            
            
              print
            
            (
            
              "
            
            
              单线程运行时间:
            
            
              "
            
            , end-
            
              start)
    
            
            
              print
            
            (
            
              "
            
            
              单线程结束:
            
            
              "
            
            .center(30, 
            
              "
            
            
              *
            
            
              "
            
            
              ))

    
            
            
              print
            
            
              ()
    
            
            
              print
            
            (
            
              "
            
            
              多线程
            
            
              "
            
            .center(30, 
            
              "
            
            
              *
            
            
              "
            
            
              ))
    start 
            
            =
            
               time()
    threads 
            
            =
            
               []
    
            
            
              for
            
             i 
            
              in
            
            
               nfuncs:
        
            
            
              #
            
            
               一个线程绑定一个函数
            
            
        t = MyThread(funcs[i], n, funcs[i].
            
              __name__
            
            
              )
        threads.append(t)

    
            
            
              for
            
             i 
            
              in
            
            
               nfuncs:
        
            
            
              #
            
            
               同时启动线程
            
            
                      threads[i].start()

    
            
            
              for
            
             i 
            
              in
            
            
               nfuncs:
        threads[i].join()
        
            
            
              print
            
            
              (threads[i].getResult())
    end 
            
            =
            
               time()
    
            
            
              print
            
            (
            
              "
            
            
              多线程运行时间:
            
            
              "
            
            , end-
            
              start)
    
            
            
              print
            
            (
            
              "
            
            
              多线程结束:
            
            
              "
            
            .center(30, 
            
              "
            
            
              *
            
            
              "
            
            
              ))

    
            
            
              print
            
            
              ()
    
            
            
              print
            
            (
            
              "
            
            
              多进程
            
            
              "
            
            .center(30, 
            
              "
            
            
              *
            
            
              "
            
            
              ))
    start 
            
            =
            
               time()
    process_list 
            
            =
            
               []
    
            
            
              for
            
             i 
            
              in
            
            
               nfuncs:
        
            
            
              #
            
            
               一个进程绑定一个函数
            
            
        t = Process(target=funcs[i], args=
            
              (n, ))
        process_list.append(t)

    
            
            
              for
            
             i 
            
              in
            
            
               nfuncs:
        
            
            
              #
            
            
               同时启动进程
            
            
                      process_list[i].start()

    
            
            
              for
            
             i 
            
              in
            
            
               nfuncs:
        process_list[i].join()
    end 
            
            =
            
               time()
    
            
            
              print
            
            (
            
              "
            
            
              多进程运行时间:
            
            
              "
            
            , end -
            
               start)
    
            
            
              print
            
            (
            
              "
            
            
              多进程结束:
            
            
              "
            
            .center(30, 
            
              "
            
            
              *
            
            
              "
            
            
              ))



            
            
              if
            
            
              __name__
            
             == 
            
              "
            
            
              __main__
            
            
              "
            
            
              :
    main()
            
          

 


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论