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

溫馨提示×

溫馨提示×

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

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

Python 中怎么接管鍵盤中斷信號

發布時間:2021-07-05 17:38:24 來源:億速云 閱讀:135 作者:Leah 欄目:編程語言

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 中怎么接管鍵盤中斷信號的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

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

AI

灵川县| 改则县| 新乐市| 府谷县| 合作市| 来安县| 富蕴县| 华阴市| 新野县| 台湾省| 怀来县| 彭山县| 台东县| 常熟市| 大冶市| 安阳县| 靖边县| 托克托县| 祁连县| 大姚县| 于都县| 靖西县| 新龙县| 二手房| 渑池县| 宜丰县| 延寿县| 土默特右旗| 安宁市| 旬邑县| 保靖县| 游戏| 淄博市| 达州市| 武安市| 金堂县| 文水县| 正阳县| 江达县| 长白| 勃利县|