国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

在 Python 中接管鍵盤中斷信號的實現方法

2020-02-15 21:25:58
字體:
來源:轉載
供稿:網友

假設有這樣一個需求,你需要從 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)             
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 浮梁县| 禄丰县| 昌乐县| 临清市| 辽中县| 微博| 岑巩县| 白银市| 融水| 永和县| 泗水县| 永州市| 喀喇| 新邵县| 瑞金市| 遂川县| 沧源| 和平县| 金溪县| 梅河口市| 朝阳县| 桃园市| 吉隆县| 肇东市| 荥经县| 保德县| 北川| 黔西县| 合作市| 黎城县| 大同市| 忻州市| 沙雅县| 新田县| 平顺县| 唐山市| 澄城县| 丹阳市| 宝山区| 清水河县| 津市市|