簡體   English   中英

Raspberry Pi 上的多線程 Python 程序中的二進制文件下載非常慢

[英]Very Slow Binary File Download in Multithreaded Python Program on Raspberry Pi

我正在 Raspberry Pi 4 上編寫一個多線程 Python 應用程序,該應用程序偶爾需要從服務器下載大約 200 KB 的二進制文件,在測試期間,該服務器是我在本地網絡上的筆記本電腦。 我已經使用 Curl 或 Python 驗證了這些文件由我的筆記本電腦在大約一秒鍾內提供服務 3 CLI requests.get 調用 RPi,但在我的應用程序中,請求下載調用在完成前至少掛起 2 分鍾。 受影響的代碼在這里:

# requests current composite from server 
# args:     timestamp: timestamp of last update
# returns:  SUCCESS_RETURN if updated, NONE_RETURN otherwise, OFFLINE_RETURN on failure to connect

def getcomposite(self, timestamp=None):
    try:
        self.slplogger.info("Downloading composite for timestamp %s" % (dt.utcfromtimestamp(timestamp).strftime("%Y-%m-%d-%H:%M:%S") if timestamp else "None"))

        # HANGS HERE
        compositeresp = requests.post(SERVER_URL + "getcomposite", data={'mac' : self.mac, 'timestamp' : timestamp})

        self.slplogger.info("Downloaded new composite: %s" % str(compositeresp.text[:min(10, len(compositeresp.text))]))

        if compositeresp.text != NONE_RETURN and compositeresp.content:
            with self.compositelock:
                self.compositedata = np.load(BytesIO(compositeresp.content), allow_pickle=False)
                # compute new input norm for adding subsequent input
                self.compositenorm = np.mean(self.compositedata[:]['value'], dtype=int)
                self.emptycomposite = False
                self.slplogger.info("Set new composite: %s" % str(self.compositedata[:min(10, len(self.compositedata))]))
            return SUCCESS_RETURN
        return FAILURE_RETURN
    except requests.exceptions.ConnectionError:

        self.slplogger.info("Composite download failed. Unable to connect to server")
        return OFFLINE_RETURN

這里定義了調用該方法的非守護線程(COMPOSITE_POLL_INTERVAL 為 2 秒):

# --------------------------------------------------------------------
#   CompositePollingThread - Thread superclass that periodically 
#   polls strangeloop server for new additions to the composite loop
# --------------------------------------------------------------------

class CompositePollingThread(Thread):

    # overloaded Thread constructor
    # args:     pedal: parent Pedal object that instantiated this thread

    def __init__(self, pedal):
        Thread.__init__(self)
        self.stop = Event()
        self.pedal = pedal
        self.timestamp = None

        self.pedal.slplogger.debug("Initialized composite polling thread")

    # main thread execution loop

    def run(self):

        self.pedal.slplogger.debug("Started composite polling thread")

        while self.pedal.running:
            time.sleep(COMPOSITE_POLL_INTERVAL)

            # timestamp to determine whether any new data needs to be downloaded
            if not self.pedal.recording and self.pedal.getcomposite(timestamp=self.timestamp) == SUCCESS_RETURN:
                self.timestamp = dt.utcnow().timestamp()

                self.pedal.slplogger.debug("Downloaded new composite at %s" % dt.utcfromtimestamp(self.timestamp).strftime("%Y-%m-%d-%H:%M:%S"))

        self.pedal.slplogger.debug("Ended composite polling thread")

我假設這個緩慢的下載是由程序中的線程問題引起的。 它還負責處理占用大部分 CPU 的實時輸入。 我能做些什么來提高這個下載速度嗎? 有沒有辦法給線程更高的優先級,或者我應該切換到多處理模塊以利用 RPi 4 的多核?

最后,問題出在服務器上。 I changed the endpoint response from a "flask.send_file" with a BytesIO wrapper around the data I needed to a simple flask.Response object with the data as the text (similar to Serve image stored in SQLAlchemy LargeBinary column ), and now it downloads不到十秒鍾。 我不知道為什么只有在通過程序訪問(而不是 CLI 請求)時才需要這么長時間才能下載,但是這種更改解決了它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM