今天小編給大家分享一下Python如何接管鍵盤中斷信號的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

網站建設哪家好,找成都創新互聯!專注于網頁設計、網站建設、微信開發、微信小程序開發、集團企業網站建設等服務項目。為回饋新老客戶創新互聯還提供了當雄免費建站歡迎大家使用!
假設有這樣一個需求,你需要從 redis 中持續不斷讀取數據,并把這些數據寫入到 MongoDB 中。你可能會這樣寫代碼:
import json import redis import pymongo client = redis.Redis() handler = pymongo.MongoClient().example.col while True: data_raw = client.blpop('data', timeout=300) if not data_raw: continue data = json.loads(data_raw[1].decode()) handler.insert_one(data)但這樣寫有一個問題,就是每來一條數據都要連接一次 MongoDB,大量時間浪費在了網絡 I/O上。
于是大家會把代碼改成下面這樣:
import json import redis import pymongo client = redis.Redis() handler = pymongo.MongoClient().example.col to_be_insert = [] while True: data_raw = client.blpop('data', timeout=300) if not data_raw: continue data = json.loads(data_raw[1].decode()) to_be_insert.append(data) if len(to_be_insert) >= 1000: handler.insert_many(to_be_insert) to_be_insert = []每湊夠1000條數據,批量寫入到 MongoDB 中。
現在又面臨另外一個問題。假設因為某種原因,我需要更新這個程序,于是我按下了鍵盤上的Ctrl + C強制關閉了這個程序。而此時to_be_insert列表里面有999條數據將會永久丟失——它們已經被從 Redis 中刪除了,但又沒有來得及寫入 MongoDB 中。
我想實現,當我按下 Ctrl + C 時,程序不再從 Redis 中讀取數據,但會先把to_be_insert中的數據(無論有幾條)都插入 MongoDB 中。最后再關閉程序。
要實現這個需求,就必須在我們按下Ctrl + C時,程序還能繼續運行一段代碼。可問題是按下Ctrl + C時,程序就直接結束了,如何還能再運行一段代碼?
實際上,當我們按下鍵盤上的Ctrl + C時,Python 收到一個名為SIGINT的信號。具體規則可以閱讀官方文檔。收到信號以后,Python 會調用一個信號回調函數。只不過默認的回調函數就是讓程序拋出一個 KeyboardInterrupt異常導致程序關閉。現在,我們可以設法讓 Python 使用我們自定義的一段函數來作為信號回調函數。
要使用信號,我們需用導入 Python 的signal庫。然后自定義一個信號回調函數,當 Python 收到某個信號時,調用這個函數。
所以我們修改一下上面的代碼:
import signal import json import redis import pymongo client = redis.Redis() handler = pymongo.MongoClient().example.col stop = False def keyboard_handler(signum, frame): global stop stop = True signal.signal(signal.SIGINT, keyboard_handler) to_be_insert = [] while not stop: data_raw = client.blpop('data', timeout=300) if not data_raw: continue data = json.loads(data_raw[1].decode()) to_be_insert.append(data) if len(to_be_insert) >= 1000: handler.insert_many(to_be_insert) to_be_insert = [] if to_be_insert: handler.insert_many(to_be_insert)我們定義了一個全局變量stop,默認為 False,所以默認情況下,while not stop所在的循環體會持續運行。
我們定義了一個函數keyboard_handler,它的作用是修改全局變量stop為 True。需要注意的是,在函數里面修改全局變量,必須先使用global 變量名聲明這個變量為全局變量。否則無法修改。
修改以后,while not stop循環停止,于是程序進入:
if to_be_insert: handler.insert_many(to_be_insert)
只要列表里面有數據,就會批量插入 MongoDB 中。然后程序結束。
整段代碼的關鍵就在signal.signal(signal.SIGINT, keyboard_handler)這里把信號SIGINT與函數keyboard_handler關聯上了,于是,在上面這段代碼運行的任何時候,只要按下鍵盤的Ctrl + C,程序就會進入keyboard_handler函數里面,優先執行這個函數里面的代碼。執行完成以后,回到之前中斷的地方,繼續執行之前沒有完成的代碼。而由于在函數里面我已經修改了stop的值,所以原來的循環不能繼續執行,于是進入最后的收尾工作。
需要注意的是,如果你的整個代碼全都是使用 Python 寫的,那么 signal可以在你程序的任何階段觸發,只要你按下 Ctrl + C,立刻就會進入設置好的信號回調函數中。
以上就是“Python如何接管鍵盤中斷信號”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注創新互聯行業資訊頻道。
分享標題:Python如何接管鍵盤中斷信號
鏈接分享:http://www.yijiale78.com/article16/gipedg.html
成都網站建設公司_創新互聯,為您提供關鍵詞優化、企業建站、網站排名、網站設計、、微信公眾號
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯