繁体   English   中英

time.sleep(300) 不允许脚本停止线程 | python |

[英]time.sleep(300) not allowing script to stop thread | python |

我正在编写代码以每 5 分钟ONOFF将数据插入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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM