python-3.x - 如果文件夹被修改,如何使用看门狗并在主线程中执行某些操作?

标签 python-3.x scikit-learn watchdog joblib

我正在寻找一个看门狗,我发现了 this很棒的图书馆。我需要安装DBSCAN模型(如果在文件夹中创建文件)。 Joblib 用于 scikit-learn 的 DBSCAN 实现,如果 DBSCAN 运行代码不在主线程中,则 joblib 不允许使用多处理。如果我使用看门狗,DBSCAN 代码将无法在主线程中运行。我该如何解决这个问题?您可以在下面找到看门狗脚本和一个简单的函数来测试它。当我运行main_watchdog.py时并在看门狗正在监视的文件夹中添加一个文件,它会运行 simple_function.py线程1中。同时,main_watchdog.py主线程中运行。

PS:解决方案可以是每次调用 simple_function.py 时启动一个子进程。但我担心如果在 watchdog 文件夹中创建多个文件,这可能会导致一些问题。想象一下一次接收 10 个、100 个或 10000 个文件......

#main_watchdog.py
import time
import logging
import threading
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
from a_function import simple_function

class Event(LoggingEventHandler):
    def on_created(self, event):
        simple_function(x)

    def on_modified(self, event):
        simple_function(x)

if __name__ == "__main__":
    x = 1
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    # path = sys.argv[1] if len(sys.argv) > 1 else '.'
    path = '/path/to/watch/the/folder'
    event_handler = Event()
    observer = Observer()
    observer.schedule(event_handler, path, recursive=False)
    observer.start()
    try:
        while True:
            time.sleep(1)
            print(threading.current_thread().name)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()
#a_function.py
import threading
def simple_function(x):
    x += 1
    print(threading.current_thread().name)
    print(x)

最佳答案

如果我要正确理解这个问题,您需要业务逻辑在主线程中运行,观察者在后台线程中运行。 通过使用线程库在后台调用观察者线程,然后通过队列(线程之间通信的一种方式)将这些事件的值传递给函数调用,可以轻松解决此问题。

#main_watchdog.py
import time
import logging
import threading
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
from a_function import simple_function
import sys
from queue import Queue

q = Queue()
x = 1
class Event(LoggingEventHandler):
    def on_created(self, event):
        q.put(x)
    def on_modified(self, event):
        q.put(x)

def run_observer():
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    path = sys.argv[1] if len(sys.argv) > 1 else '.'
    # path = '/path/to/watch/the/folder'
    event_handler = Event()
    observer = Observer()
    observer.schedule(event_handler, path, recursive=False)
    observer.start()
    while True:
        time.sleep(1)
        print(threading.currentThread().name)

if __name__ == "__main__":
    background_thread = threading.Thread(target=run_observer, args=())
    background_thread.daemon = True
    background_thread.start()
    print('Business logic')
    while True:
        val = q.get(True)
        simple_function(val)


其他功能保持不变。

关于python-3.x - 如果文件夹被修改,如何使用看门狗并在主线程中执行某些操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58862466/

相关文章:

python - Pycurl 和 io.StringIO - pycurl.error : (23, '写入正文失败)

python - 根据另一个字符串列表(例如黑名单字符串)从字符串列表中每个元素的末尾删除字符

python - 我在 spyder 上看到“"TypeError: ' 元组对象不支持项目分配”

python - 使用 scikit-learn 时,如何找到我的树 split 的属性?

python - 在 sklearn/pandas 中编码 "k out of n labels"功能

c - STM32f429ZI 无需调试器即可记录调用堆栈

systemd - 如何在 systemd 的看门狗停止服务之前运行特定程序

python - 如何生成一些全为奇数的随机数

python - 检查相等列表

multithreading - 在Perl中实现看门狗