You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python线程/进程间数据传递峰值延迟过高的排查与优化问询

Python线程/进程间数据传递峰值延迟过高的排查与优化问询

我正在开发一个音频应用,要求“音频循环”里所有函数的执行时间远小于1ms。我知道Python不是做这个任务的最优选择,但Python现在已经发展得很好了,我相信通过正确的技巧和调整可以让它正常工作。

目前我在研究线程/进程间的数据传递方法,发现了一些奇怪的结果。我运行了下面的基准测试程序来对比不同方法:

import multiprocessing
import threading
import queue
import numpy as np
import time

SIZE = 2048
myarray1 = np.ones(SIZE)
myarray2 = np.ones(SIZE)

def test_multiprocessing(num: int, put: list, get: list):
  # init
  shared_array = multiprocessing.Array('f', SIZE, lock=True)
  for _ in range(num):
    starttime = time.perf_counter()
    # put
    with shared_array.get_lock():
      np.copyto(np.frombuffer(shared_array.get_obj(), dtype=np.float32), myarray1)
    endtime = time.perf_counter()
    put.append(endtime-starttime)

    starttime = time.perf_counter()
    # get
    with shared_array.get_lock():
      np.copyto(myarray2, np.frombuffer(shared_array.get_obj(), dtype=np.float32))
    endtime = time.perf_counter()
    get.append(endtime-starttime)

def test_threading_copy(num: int, put: list, get: list):
  # init
  free = threading.Semaphore(value=1)
  used = threading.Semaphore(value=0)
  transfer = np.empty(SIZE)
  for _ in range(num):
    
    starttime = time.perf_counter()
    # put
    free.acquire()
    np.copyto(transfer, myarray1)
    used.release()
    endtime = time.perf_counter()
    put.append(endtime-starttime)

    starttime = time.perf_counter()
    # get
    used.acquire()
    np.copyto(myarray2, transfer)
    free.release()
    endtime = time.perf_counter()
    get.append(endtime-starttime)

def test_queue(num: int, put: list, get: list):
  # init
  q = queue.Queue(maxsize=1)
  for _ in range(num):
    starttime = time.perf_counter()
    # put
    q.put(myarray1)
    endtime = time.perf_counter()
    put.append(endtime-starttime)
    
    starttime = time.perf_counter()
    # get
    myarray2 = q.get()
    endtime = time.perf_counter()
    get.append(endtime-starttime)

if __name__ == "__main__":
  nums = int(1e6)
  for test in [test_multiprocessing, test_threading_copy, test_queue]:
    put = []; get = []
    test(nums, put, get)
    print("results:")
    print(f"\tput_avg = {sum(put) / len(put)}")
    print(f"\tput_max = {max(put)}")
    print(f"\tget_avg = {sum(get) / len(get)}")
    print(f"\tget_max = {max(get)}")

我机器上的测试结果大致如下:

results:
        put_avg = 3.930823400122108e-06
        put_max = 0.002819699999918157
        get_avg = 3.895689899812624e-06
        get_max = 0.0016344000000572123
results:
        put_avg = 3.603283000182273e-06
        put_max = 0.007975700000088182
        get_avg = 3.501774700153874e-06
        get_max = 0.010190099999817903
results:
        put_avg = 1.4336647000006905e-06
        put_max = 0.0008001000001058856
        get_avg = 1.2777225000797898e-06
        get_max = 0.00023200000009637733

平均时间完全符合我的应用要求,但峰值延迟却让我很头疼——它们都超过或接近1ms了。除了test_queue的例子,我的代码都没有分配新内存。

我有几个问题想请教:

  • 你知道为什么会出现这种峰值延迟吗?
  • 我该如何修复或加速这段代码?
  • 有没有通用的Python设置可以避免这种情况?
  • 你会怎么调试这个问题?

备注:内容来源于stack exchange,提问作者helixfoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:28:06