<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python 獲取線程返回值的三種方式

          共 2931字,需瀏覽 6分鐘

           ·

          2022-07-10 00:50

          提到線程,你的大腦應(yīng)該有這樣的印象:我們可以控制它何時(shí)開始,卻無法控制它何時(shí)結(jié)束,那么如何獲取線程的返回值呢?今天就分享一下自己的一些做法。

          方法一:使用全局變量的列表,來保存返回值

          ret_values = []

          def thread_func(*args):
              ...
              value = ...
              ret_values.append(value)

          選擇列表的一個(gè)原因是:列表的 append() 方法是線程安全的,CPython 中,GIL 防止對它們的并發(fā)訪問。如果你使用自定義的數(shù)據(jù)結(jié)構(gòu),在并發(fā)修改數(shù)據(jù)的地方需要加線程鎖。

          如果事先知道有多少個(gè)線程,可以定義一個(gè)固定長度的列表,然后根據(jù)索引來存放返回值,比如:

          from threading import Thread

          threads = [None] * 10
          results = [None] * 10

          def foo(bar, result, index):
              result[index] = f"foo-{index}"

          for i in range(len(threads)):
              threads[i] = Thread(target=foo, args=('world!', results, i))
              threads[i].start()

          for i in range(len(threads)):
              threads[i].join()

          print (" ".join(results))

          方法二:重寫 Thread 的 join 方法,返回線程函數(shù)的返回值

          默認(rèn)的 thread.join() 方法只是等待線程函數(shù)結(jié)束,沒有返回值,我們可以在此處返回函數(shù)的運(yùn)行結(jié)果,代碼如下:

          from threading import Thread


          def foo(arg):
              return arg


          class ThreadWithReturnValue(Thread):
              def run(self):
                  if self._target is not None:
                      self._return = self._target(*self._args, **self._kwargs)

              def join(self):
                  super().join()
                  return self._return


          twrv = ThreadWithReturnValue(target=foo, args=("hello world",))
          twrv.start()
          print(twrv.join()) # 此處會(huì)打印 hello world。

          這樣當(dāng)我們調(diào)用 thread.join() 等待線程結(jié)束的時(shí)候,也就得到了線程的返回值。

          方法三:使用標(biāo)準(zhǔn)庫 concurrent.futures

          我覺得前兩種方式實(shí)在太低級了,Python 的標(biāo)準(zhǔn)庫 concurrent.futures 提供更高級的線程操作,可以直接獲取線程的返回值,相當(dāng)優(yōu)雅,代碼如下:

          import concurrent.futures


          def foo(bar):
              return bar


          with concurrent.futures.ThreadPoolExecutor(max_workers=10as executor:
              to_do = []
              for i in range(10):  # 模擬多個(gè)任務(wù)
                  future = executor.submit(foo, f"hello world! {i}")
                  to_do.append(future)

              for future in concurrent.futures.as_completed(to_do):  # 并發(fā)執(zhí)行
                  print(future.result())

          某次運(yùn)行的結(jié)果如下:

          hello world! 8
          hello world! 3
          hello world! 5
          hello world! 2
          hello world! 9
          hello world! 7
          hello world! 4
          hello world! 0
          hello world! 1
          hello world! 6

          最后的話

          本文分享了獲取線程返回值的 3 種方法,推薦使用第三種,如果你有更好的方法,請留言告訴我。

          瀏覽 40
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  围内精品久久久久久久久久98 | 亚洲黄色片免费看 | 成人黄色在线观看 | 国产精品一区在线观看 | 夜噜噜久久国产欧美日韩精品 |