gpt4 book ai didi

python - 定期或在事件触发时执行函数

转载 作者:行者123 更新时间:2023-12-03 15:54:56 25 4
gpt4 key购买 nike

我正在处理 Python 的 Flask 服务器端代码,其中有一个后台任务会定期运行并执行一个函数(请注意,“定期”不是那么强硬,执行一次,然后在 x 秒后也有效)。但是我也需要它在服务器收到请求时立即执行相同的功能(然后恢复后台任务)。

这种让我想起 C 中的 SELECT 系统调用,系统等待超时或直到数据包到达。

这是我在查找了很多答案后最少想到的。

from flask import Flask, request
import threading, os, time

POOL_TIME = 2

myThread = threading.Thread()

def pollAndExecute(a='|'):
time.sleep(1)
print(time.time(), a)
# time.sleep(1)
myThread = threading.Timer(POOL_TIME, pollAndExecute)
myThread.start()

def startWork():
global myThread
myThread = threading.Timer(POOL_TIME, pollAndExecute)
myThread.start()

app = Flask(__name__)

@app.route('/ping', methods=['POST'])
def ping():
global myThread
myThread.cancel()
pollAndExecute("@")
return "Hello"

if __name__ == '__main__':
app.secret_key = os.urandom(12)
startWork()
app.run(port=5001)

输出:

Output

但是输出清楚地表明它在有请求后表现不正常(使用 curl -X POST http://localhost:5001/ping 发送)

请指导我如何纠正这个问题,或者有没有其他方法可以做到这一点。仅供引用,在原始代码中, pollAndExecute() 中也有各种数据库更新,我需要注意轮询和 ping 之间没有竞争条件。不用说,在特定时间(最好在单个线程中)应该只执行函数的一个副本。

最佳答案

这是我为您的问题制定的解决方案。我使用了一个优先级队列,它接收要与 printTime 一起运行的数据。功能。后台和 flask 函数是两个不同的线程,它们将数据推送到优先级队列中,这应该优先于后台调用 flask 。注意它现在如何在执行另一个线程之前等待当前线程完成。

from flask import Flask, request
import threading, os, time

from threading import Thread, Lock
from queue import PriorityQueue

POOL_TIME = 2

lock = Lock()

def printTime(a='|'):
time.sleep(1) # Simulate process taking 1 sec
print(time.time(), a)

jobs = PriorityQueue()

class Queue(Thread):
def __init__(self):
Thread.__init__(self)
self.daemon = True
self.start()
def run(self):
while True:
_, data = jobs.get()
printTime(data)


class backGroundProcess(Thread):
def __init__(self):
Thread.__init__(self)
self.daemon = True
self.start()
def run(self):
while True:
time.sleep(2) # Background process enqueues a job every 2 secs
jobs.put((0,"|"))

class flaskProcess(Thread):
def __init__(self):
Thread.__init__(self)
self.start()
def run(self):
jobs.put((1,"@"))


app = Flask(__name__)

@app.route('/ping', methods=['POST'])
def ping():
flaskThread = flaskProcess()
return "Hello"

if __name__ == '__main__':
backGroundProcess()
Queue()
app.secret_key = os.urandom(12)
app.run(port=5001)

上面的代码片段可能有点冗长,因为我使用了类,但这应该可以帮助您入门。

关于python - 定期或在事件触发时执行函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58769862/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com