Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 服务器长轮询并启动每个RFID卡号调用的子进程。如果这种情况持续太久,我的服务器将崩溃。我怎样才能做得更好?_Python_Web_Flask_Subprocess - Fatal编程技术网

Python 服务器长轮询并启动每个RFID卡号调用的子进程。如果这种情况持续太久,我的服务器将崩溃。我怎样才能做得更好?

Python 服务器长轮询并启动每个RFID卡号调用的子进程。如果这种情况持续太久,我的服务器将崩溃。我怎样才能做得更好?,python,web,flask,subprocess,Python,Web,Flask,Subprocess,我需要从RFID阅读器获取RFID卡号。客户端发起此操作。客户端AJAX发布到“/user/rfid”路由。此路由返回“错误…”或rfid卡号。服务器打开检索此编号的子进程。如果服务器静坐一段时间,用户试图使用RFID登录,服务器将中断。我需要一个更好的方法来完成这个任务,或者至少清理子流程 有什么建议吗 烧瓶路径 @app.route("/user/rfid", methods=["POST"]) def user_rfid(): rfid = subprocess.Popen(["p

我需要从RFID阅读器获取RFID卡号。客户端发起此操作。客户端AJAX发布到“/user/rfid”路由。此路由返回“错误…”或rfid卡号。服务器打开检索此编号的子进程。如果服务器静坐一段时间,用户试图使用RFID登录,服务器将中断。我需要一个更好的方法来完成这个任务,或者至少清理子流程

有什么建议吗

烧瓶路径

@app.route("/user/rfid", methods=["POST"])
def user_rfid():
    rfid = subprocess.Popen(["python", "rfidSimple.py"], stdout=subprocess.PIPE).stdout.read()
    print("rfid read: %s" % rfid)
    if(rfid == "Exiting...."):
        return json.dumps({"error":"rfid reader failure"})
    else:
        user = db.getUserByRFID(rfid.replace(" ",""))
        if("id" in user.keys()):
            # if credentials match, add user to session
            session["id"]       = user["id"]
            # return redirect url
            return json.dumps({"url":url_for("kiosk")})
        else:
            return json.dumps({"error":"rfid reader failure"})
rfidSimple.py

#!/usr/bin/env python

#Basic imports
from ctypes import *
import sys
#Phidget specific imports
from Phidgets.PhidgetException import PhidgetErrorCodes, PhidgetException
from Phidgets.Events.Events import AttachEventArgs, DetachEventArgs, ErrorEventArgs, OutputChangeEventArgs, TagEventArgs
from Phidgets.Devices.RFID import RFID, RFIDTagProtocol

# Rudimentary wait system variable
x = True
def rfidTagGained(e):
    global x
    source = e.device
    sys.stdout.write(e.tag)
    x = False

def main():
     #Create an RFID object
    try:
        rfid = RFID()
    except RuntimeError as e:
        sys.stdout.write("Exiting...")
    try:
        rfid.setOnTagHandler(rfidTagGained)
    except PhidgetException as e:
        sys.stdout.write("Exiting...")
    try:
        rfid.openPhidget()
    except PhidgetException as e:
        sys.stdout.write("Exiting...")

    try:
        rfid.waitForAttach(10000)
    except PhidgetException as e:
        # print("Phidget Exception %i: %s" % (e.code, e.details))
        try:
            rfid.closePhidget()
        except PhidgetException as e:
            sys.stdout.write("Exiting...")
    rfid.setAntennaOn(True)
    while x:
        # wait wait wait!
        pass
    exit(1)

if __name__ == '__main__':
    main()

您可以启动一个单独的线程来读取进程stdout。在线程上执行连接(超时),如果线程没有终止,您知道调用花费的时间太长,您可以终止它。下面是一个示例,其中所有内容都包装到一个类中。我没有测试它,它可能有错误,但你可能会发现这个想法很有用

import threading
import subprocess
import time

class RfidSimple(threading.Thread):

    def __init__(self, timeout=10):
        super(theading.Thread, self).__init__()
        self.end = time.time() + timeout
        self.proc = subprocess.Popen(["python", "rfidSimple.py"],
            stdout=subprocess.PIPE)
        self.start()

    def run(self):
        self._result = self.proc.stdout.read()

    @property
    def result(self):
        timeout = self.end - time.time()
        if timeout > 0:
            self.join(timeout)
            if not self.isAlive():
                self.proc.wait()
                return self._result
        self.proc.terminate()
        self.join(5)
        if not self.isAlive():
            self.proc.wait()
            return "Exiting..."
        raise Exception("could not kill subprocess")

def user_rfid():
    rfid = RfidSimple().result
    print("rfid read: %s" % rfid)
    if(rfid == "Exiting...."):
        return json.dumps({"error":"rfid reader failure"})
    else:
        user = db.getUserByRFID(rfid.replace(" ",""))
        if("id" in user.keys()):
            # if credentials match, add user to session
            session["id"]       = user["id"]
            # return redirect url
            return json.dumps({"url":url_for("kiosk")})
        else:
            return json.dumps({"error":"rfid reader failure"})

我不明白。。。如果rfidSimple.py超时的时间太长,您想要一种超时方法吗?我将尝试此方法并挤压存在的错误。我要到下班后才能回到这个项目,所以我会在晚上开始。希望这是更好的解决方案!现在开始测试(让AJAX“对话”保持15分钟左右)。不过我得承认。一种可能的情况是,如果longpoll收件人不再存在(用户使用凭据而不是RFID登录)。可能只有一个线程。另外,如果我登录超过4次,我的服务器会锁定。。。啊,啊,啊