[英]How to use time.sleep in an if statement and not stop the rest of the script
[英]time.sleep(300) not allowing script to stop thread | python |
我正在编写代码以每 5 分钟ON
和OFF
将数据插入mongodb
这里的问题是关键字中断我的线程应该停止并退出代码执行
将第一条记录插入数据库后,我的time.sleep(300)
将使脚本休眠,并且在我的终端上出现以下行 -> Press enter to kill the running thread:
万一如果我改变主意不想跑
只需当我从键盘按回车键时,正在运行且处于睡眠状态的线程应该停止并退出
我的目标是根据用户的输入停止线程
我的代码:
import datetime
import threading
import pymongo
import time
from pymongo import MongoClient
dbUrl = pymongo.MongoClient("mongodb://localhost:1245/")
dbName = dbUrl["student"]
dbCollectionName = dbName["student_course"]
def doremon():
return "Hi Friends"
def insert_to_mongodb():
global kill_the_running_thread
while (not kill_the_running_thread):
note_start_time = datetime.datetime.now()
msg = doremon()
note_end_time = datetime.datetime.now()
dt = {"message": msg, "start_time": note_start_time, "end_time": note_end_time}
rec_id1 = dbCollectionName.insert_one(dt)
time.sleep(300)
def main():
global kill_the_running_thread
kill_the_running_thread = False
my_thread = threading.Thread(target=insert_to_mongodb)
my_thread.start()
input("Press enter to kill the running thread : ")
kill_the_running_thread = True
# Calling main
main()
您可以尝试自定义 class,如下所示:
import datetime
import threading
import pymongo
import time
from pymongo import MongoClient
dbUrl = pymongo.MongoClient("mongodb://localhost:1245/")
dbName = dbUrl["student"]
dbCollectionName = dbName["student_course"]
class ThreadWithKill(threading.Thread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._target = kwargs.get('target')
self._kill = threading.Event()
self._sleep_duration = 300 # 5 minutes
def run(self):
while True:
# If no kill signal is set, sleep for the duration of the interval.
# If kill signal comes in while sleeping, immediately wake up and handle
self._target() # execute passed function
is_killed = self._kill.wait(self._sleep_duration)
if is_killed:
break
def kill(self):
self._kill.set()
def doremon():
return "Hi Friends"
def insert_to_mongodb():
note_start_time = datetime.datetime.now()
msg = doremon()
note_end_time = datetime.datetime.now()
dt = {"message": msg, "start_time": note_start_time, "end_time": note_end_time}
rec_id1 = dbCollectionName.insert_one(dt)
def main():
my_thread = ThreadWithKill(target=insert_to_mongodb)
my_thread.start()
input("Press enter to kill the running thread : ")
my_thread.kill()
if __name__ == "__main__":
main()
这样就不需要kill_the_running_thread
变量。 你需要自己测试一下,因为我没有 mongodb。
将全局变量作为哨兵与睡眠结合使用时会出现问题。 问题是睡眠可能刚刚开始(在 OP 的情况下为 5 分钟),因此线程可能需要将近 5 分钟才能意识到它应该终止。
一个首选(我)的技术是使用队列。 您可以在队列上指定超时,当然,它几乎会立即响应传递给它的任何数据。 这是一个例子:
from threading import Thread
from queue import Queue, Empty
def process(queue):
while True:
try:
queue.get(timeout=5)
break
except Empty as e:
pass
print('Doing work')
queue = Queue()
thread = Thread(target=process, args=(queue,))
thread.start()
input('Press enter to terminate the thread: ')
queue.put(None)
thread.join()
process() function 将阻塞队列长达 5 秒(在本例中)。 如果队列中没有任何内容,它将完成它的工作。 如果有什么东西(我们只是传递 None 作为触发器),它将立即终止
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.