乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      理解 python 中多線程

       ly88 2018-03-03

      線程的有兩種使用方法,一種是在函數(shù)使用,一種是放在類中使用。

      1,在函數(shù)中使用多線程

      語法如下:

      1
      thread.start_new_thread(function, args[, kwargs] )

      參數(shù)說明:

      1
      2
      3
      function - 線程函數(shù)。
      args - 傳遞給線程函數(shù)的參數(shù),必須是個tuple類型。
      kwargs - 可選參數(shù)。

      下面是一個例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      def run(num):
          print 'hi , i am a thread.', num
      def main():
          threads = []
          for i in range(5):
              t = threading.Thread(target=run, args=(i,))
              threads.append(t)
              t.start()
          for t in threads:
              t.join()
      if __name__ == '__main__':
          print 'start -->'
          main()
          print 'go here -->'

      運行結(jié)果:

      1
      2
      3
      4
      5
      6
      7
      start -->
      hi , i am a thread. 0
      hi , i am a thread. 1
      hi , i am a thread. 2
      hi , i am a thread. 3
      hi , i am a thread. 4
      go here -->

      2,在類中多使用線程

      下面是在類中使用線程的示例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      class MyThread(threading.Thread):
          def __init__(self,num):
              self.num = num
              super(MyThread, self).__init__()
          def run(self):
              print 'i am a thread,',self.num
              time.sleep(1)
      def main():
          threads = []
          for i in range(5):
              t = MyThread(i)
              threads.append(t)
              t.start()
          for t in threads:
              t.join()
      if __name__ == '__main__':
          print 'start -->'
          main()
          print 'go here -->

      • run(),需要重寫,編寫代碼實現(xiàn)所需要的功能。
      • getName(),獲得線程對象名稱
      • setName(),設(shè)置線程對象名稱
      • start(),啟動線程
      • join([timeout]),等待另一線程結(jié)束后再運行。
      • setDaemon(bool),設(shè)置子線程是否隨主線程一起結(jié)束,必須在start() 之前調(diào)用,默認(rèn)為False
      • isDaemon(),判斷線程是否隨主線程一起結(jié)束。
      • isAlive(),檢查線程是否在運行中。

      join方法的作用是阻塞主進(jìn)程(無法執(zhí)行join以后的語句),主線程等待這個線程結(jié)束后,才可以執(zhí)行下一條指令。多線程多join的情況下,依次執(zhí)行各線程的join方法,前頭一個結(jié)束了才能執(zhí)行后面一個。無參數(shù),則等待到該線程結(jié)束,才開始執(zhí)行下一個線程的join。設(shè)置參數(shù)后,則等待該線程這么長時間就不管它了(而該線程并沒有結(jié)束)。不管的意思就是可以執(zhí)行后面的主進(jìn)程了。

      3,線程同步與互斥鎖

      線程之所以比進(jìn)程輕量,其中一個原因就是他們共享內(nèi)存。也就是各個線程可以平等的訪問內(nèi)存的數(shù)據(jù),如果在短時間“同時并行”讀取修改內(nèi)存的數(shù)據(jù),很可能造成數(shù)據(jù)不同步。例如下面的例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      var = 0
      class IncreThread(Thread):
          def run(self):
              global var
              print 'before,var is ',var
              var += 1
              print 'after,var is ',var
      def use_incre_thread():
          threads = []
          for i in range(50):
              t = IncreThread()
              threads.append(t)
              t.start()
          for t in threads:
              t.join()
          print 'After 10 times,var is ',var
      if __name__ == '__main__':
          use_incre_thread()

      有一個全局變量var,五十個線程,每個線程對var變量進(jìn)行加 1 運算,但是當(dāng)你多運行幾次后,發(fā)現(xiàn)并不是每次的運行結(jié)果都是 50,為什么呢?

      var是 10 的時候,線程t1讀取了var,這個時刻cpu將控制權(quán)給了另一個線程t2。t2線程讀到的var也是 10,t1t2都把var加到 11,當(dāng)時我們期望的是t1 t2兩個線程使var + 2 變成 12。在這里就有了資源競爭,相同的情況也可能發(fā)生在其它的線程間,所以出現(xiàn)了最后的結(jié)果小于 50 的情況。

      為了避免線程不同步造成數(shù)據(jù)不同步,可以對資源進(jìn)行加鎖。也就是訪問資源的線程需要獲得鎖,才能訪問。threading 模塊提供了一個 Lock 功能,修改代碼如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      var = 0
      lock = Lock()  #創(chuàng)建鎖
      class IncreThread(Thread):
          def run(self):
              global var
              lock.acquire()  #獲取鎖
              print 'before,var is ',var
              var += 1
              print 'after,var is ',var
              lock.release()  #釋放鎖
      def use_incre_thread():
          threads = []
          for i in range(50):
              t = IncreThread()
              threads.append(t)
              t.start()
          for t in threads:
              t.join()
          print 'After 10 times,var is ',var
      if __name__ == '__main__':
          use_incre_thread()

      雖然線程可以共享內(nèi)存,但是一個線程不能影響其他線程內(nèi)的變量(非全局變量)。

      4,死鎖

      在線程間共享多個資源的時候,如果兩個線程分別占有一部分資源并且同時等待對方的資源,就會造成死鎖。盡管死鎖很少發(fā)生,但一旦發(fā)生就會造成應(yīng)用的停止響應(yīng)。下面是一個死鎖的例子:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      mutex_a = Lock()
      mutex_b = Lock()
      class MyThread(Thread):
          def task_b(self):
              if mutex_a.acquire():
                  print 'thread get a mutex_a',self.name
                  time.sleep(1)
                  if mutex_b.acquire():
                      print 'get a mutex_b',self.name
                      mutex_b.release()
                  mutex_a.release()
          def task_a(self):
              if mutex_b.acquire():
                  print 'thread get a mutex_b',self.name
                  time.sleep(1)
                  if mutex_a.acquire():
                      print 'get a mutex_a',self.name
                      mutex_a.release()
                  mutex_b.release()
          def run(self):
              self.task_a()
              self.task_b()
      if __name__ == '__main__':
          threads = [MyThread() for i in range(2)]
          print threads
          for t in threads:
              t.start()

      線程需要執(zhí)行兩個任務(wù),兩個任務(wù)都需要獲取鎖,當(dāng)兩個任務(wù)得到鎖后,就需要等另外鎖釋放。

      5,可重入鎖

      為了支持在同一線程中多次請求同一資源,python 提供了可重入鎖(RLock)。RLock內(nèi)部維護(hù)著一個Lock和一個counter變量,counter記錄了acquire的次數(shù),從而使得資源可以被多次require。直到一個線程所有的acquire都被release,其他的線程才能獲得資源。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      mutex = threading.RLock()
      class MyThread(threading.Thread):
          def run(self):
              if mutex.acquire(1):
                  print 'threading gte mutex:',self.name
                  time.sleep(1)
                  mutex.acquire()
                  mutex.release()
                  mutex.release()
      def main():
          print 'start main threading:'
          threads = [MyThread() for i in range(2)]
          for t in threads:
              t.start()
          for t in threads:
              t.join()
          print 'end main threading.'
      if __name__ == '__main__':        
          main()

      6,后臺線程

      使用多線程默認(rèn)情況下,當(dāng)主線程退出之后,即使子線程沒有 join,子線程也依然會繼續(xù)執(zhí)行。如果希望主線程退出后,其子線程也退出而不再執(zhí)行,則需要設(shè)置子線程為后臺線程。python提供了setDaemon方法,將子線程與主線程進(jìn)行綁定,當(dāng)主線程退出時子線程的生命也隨之結(jié)束。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      class MyThread(threading.Thread):
          def run(self):
              wait_time = random.randrange(1, 10)
              print 'thread %s will wait %s s' %(self.name, wait_time)
              time.sleep(wait_time)
              time.sleep(30)
              print 'thread %s finished.' % self.name
      def main():
          print 'start thread:'
          for i in range(3):
              t = MyThread()
              t.setDaemon(1)
              t.start()
          print 'end thread.'
      if __name__ == '__main__':
          main()

      運行結(jié)果:

      1
      2
      3
      4
      5
      start thread:
      thread Thread-1 will wait 9 s
      thread Thread-2 will wait 1 s
      thread Thread-3 will wait 7 s
      end thread.

      本來子線程需要等待幾秒才能結(jié)束,但是主線程提前結(jié)束了,所以子線程也隨主線程結(jié)束了。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多