91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python多線程退出控制的方法

發布時間:2020-08-12 15:45:05 來源:億速云 閱讀:275 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關Python多線程退出控制的方法的內容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。

日常前言

最近接 到一個搶票的爬蟲外包,那個網站及其之撈,訪問購票地址竟然還要排隊,在購票高峰臨時升一下服務器配置不行嗎…沒辦法,甲方爸爸的要求還得做啊,其中一個障礙便是目標網站的后端限制了訪問頻次,俗話說:“上有政策,下有對策。” 立刻想到了多線程 + 多代理的方式進行訪問。

Python多線程退出控制的方法

但此時問題便來了,多代理還好說,再寫個爬蟲爬一堆下來就好,多線程可就麻煩多了,多線程一旦發出去了,基本等同于失控的狀態,你無法去結束或者是重啟一個線程,最多只能是獲取線程的信息,沒有實際的控制權,而且Python官方也沒有提供相應的結束函數。那么接下來,讓我們來好好聊聊解決這個問題的思路。

單線程的結束

說實話,會百度在程序世界是一個優秀的習慣,不然怎么會有這么一張表情包呢

Python多線程退出控制的方法

但是百度這一次卻不盡人意,搜了很久,結果不盡人意,基本上所有的搜索結果都告訴我只有結束單個線程的方法,我也試過循環使用百度的結束函數,但最終都只能是結束的當前的這一個線程,無法達到目標。

貼一段搜到的單線程結束代碼示例

def _async_raise(tid, exctype):
 tid = ctypes.c_long(tid)
 if not inspect.isclass(exctype):
  exctype = type(exctype)
 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
 if res == 0:
  raise ValueError("invalid thread id")
 elif res != 1:
  ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
  raise SystemError("PyThreadState_SetAsyncExc failed")
  
def stop_thread(thread):
 _async_raise(thread.ident, SystemExit)

那怎么結束多個線程呢?

既然度娘也搜不到,那就自己探索,打開python threading模塊的官方文檔,其中一個daemon屬性進入了視野,單詞翻譯過來便是守護進程,相信大家應該或多或少的聽到過,以下是官方的釋義,大概意思就是只要在啟動線程之前設置了這個屬性為True,當父進程結束時,所有的子進程跟著全部結束,這樣就好辦了,接下來看看代碼部分。

daemon
A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

完整代碼

import threading,time,random

class Messy:
 def __init__(self):
  self.__messy = 0

 def m(self,i):
		# 隨機時間進行打印
  time.sleep(random.random()*2)
  print(i)
  if i == 1:
   self.__messy = 1

 def main(self):
  Threads = []
  # 將會啟動10個線程,線程id為 1 時全部線程終止!
  for i in range(10):
   t = threading.Thread(target=self.m,args=(i,))
   t.daemon = 1
   Threads.append(t)
  # 啟動所有線程
  for i in Threads:
   i.start()
  # 當標志位【 messy 】時所有多線程結束
  while 1:
   if self.__messy:
    break
  print('線程已退出!')

Messy().main()
# 繼續執行后續程序
for i in range(5):
 print('yeah!')

此時,main這個函數對于多線程來講,便是父進程,也就是守護進程。預計會進行10次循環的數字打印,但是當self.__messy這個標志位為真時,所有的剩余子線程將不會再執行,直接結束進行后續的操作

e.g:如下圖便只打印了四次

Python多線程退出控制的方法

最后

目前來講,用設置主線程退出的方法是可以完成現在這個搶票的目標。

但是后來發現其實這么做也會帶來很多壞處,直接殺掉所有子線程對系統來說是一個很粗魯的行為,如果涉及到的操作包括了文件數據、數據庫數據的改動的話,內存無法被合理釋放(之前就遇到過CPU莫名占用滿),極有可能造成數據丟失甚至系統中斷

我這里只是一個搶票的小程序,子線程只用到了POST,網絡請求中斷帶來的影響還是相對來講比較小的,所以大家酌情使用本篇所介紹的方法。

感謝各位的閱讀!關于Python多線程退出控制的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

朝阳市| 吉安县| 武夷山市| 钟山县| 资兴市| 台前县| 兴海县| 思南县| 和平县| 芒康县| 三江| 兴山县| 明溪县| 南宫市| 博乐市| 江西省| 晋宁县| 尉犁县| 周口市| 新晃| 和龙市| 余庆县| 靖远县| 汨罗市| 蒙阴县| 岳普湖县| 平潭县| 秦安县| 财经| 仪陇县| 广宗县| 榕江县| 宜宾县| 贵阳市| 津市市| 耒阳市| 蚌埠市| 杨浦区| 普陀区| 望城县| 苗栗市|