【问题标题】:Address already in use when running flask in another process在另一个进程中运行烧瓶时地址已被使用
【发布时间】:2020-07-20 15:55:14
【问题描述】:

我正在为 IoT 应用程序开发摄像头端点,我想根据命令启动和停止烧瓶应用程序以显示带有流式摄像头数据的网页。我有所有单独的部分工作,但当我把它们放在一起时它失败了。

如果我在启动另一个线程后启动烧瓶进程,它会抱怨地址已在使用中。这是一个精简的示例:

#!/usr/bin/env python3

import os
import threading
from flask import Flask
import socket
import time
from multiprocessing import Process

app = Flask(__name__)

def main():
    start_thread(udp_listener)
    start_process(runflask)

    while True:
        time.sleep(1)

def start_thread(function, arguments=()):
    th = threading.Thread(target=function, args=arguments)
    th.daemon = True
    th.start()

def start_process(function):
    server = Process(target=function)
    server.start()
    while True:
        time.sleep(60)
    server.terminate()
    server.join()

def udp_listener():
    while True:
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            s.bind(('', 9000))
            print('udp listening on port 9000')
            while True:
                data, server = s.recvfrom(4069)
                print('received:')

def runflask():
    app.run(host='0.0.0.0', port=8001, debug=True)

if __name__ == "__main__":
    main()

注释掉 start_thread() 并运行 start_process() 就可以了。 注释掉 start_process() 并运行 start_thread() 就可以了。 运行两者并获得地址已在使用中的错误,即使它们正在侦听不同的端口。

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
File "/usr/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
File "./webcam_test.py", line 35, in udp_listener
    s.bind(('', 9000))
OSError: [Errno 98] Address already in use

我想以一种可以让我根据命令启动和停止它的方式运行烧瓶应用程序。我应该换一种方式吗?

【问题讨论】:

    标签: python sockets flask


    【解决方案1】:

    我能够通过使用此处指定的 ServerThread 来解决此问题:How to stop flask application without using ctrl-c

    重要的是要注意调用这个 ServerThread 会自动阻塞,所以如果你想要一个可中断的线程,你需要将它实例化为另一个线程的子线程。我的设计已经为每种相机模式产生了线程,所以现在我有一个线程调用一个线程调用一个线程:)。

    我仍然不知道为什么烧瓶在作为进程运行时会抱怨不相关的侦听套接字,但现在我有一个解决方法。

    【讨论】:

      【解决方案2】:

      不要说这仍然是多么相关,但是:

      快速浏览一下,我没有看到您正在绑定的套接字 (s.bind(('', 9000))) 正在关闭的任何地方。由于它在一个循环中,它试图绑定一个再次使用的套接字,因此错误?在再次绑定之前应该停止它:

      s.shutdown(1)
      s.close()
      

      如果是这种情况,我建议的第一个解决方案是正确关闭套接字,而不是在循环中启动它(为什么首先要在循环中绑定套接字?)

      如果仅此一项没有帮助,请允许套接字重用地址:

      s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      

      Python: Binding Socket: "Address already in use"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-27
        • 1970-01-01
        • 2020-10-24
        • 1970-01-01
        • 1970-01-01
        • 2019-09-10
        • 2018-10-25
        • 2022-11-24
        相关资源
        最近更新 更多