【问题标题】:How to synchronize the start time of python threads?如何同步python线程的启动时间?
【发布时间】:2021-01-22 04:01:37
【问题描述】:

我想测量信号的时间延迟。为此,将信号放在扬声器上,并估计它被麦克风捕获时的延迟。延迟预计在毫秒范围内,因此在完全相同的时间启动扬声器信号和测量至关重要。

我的问题是是否可以通过使用线程来实现:

def play_sound():
    # play sound

def record():
    # start recording


if __name__ == '__main__':
    t1 = threading.Thread(target=play_sound())
    t2 = threading.Thread(target=record())

    t1.start()
    t2.start()

或者有更好的方法吗?

【问题讨论】:

    标签: python audio synchronization


    【解决方案1】:

    它不会 100% 实时并发,但桌面解决方案永远不会。那么问题就变成了它是否对您的应用程序足够准确。要知道这一点,您只需运行一些已知延迟的测试,看看它是否有效。

    你应该知道全局解释器锁:https://docs.python.org/3.3/glossary.html#term-global-interpreter-lock。这意味着即使在多核 PC 上,您的代码也不会真正并发运行。

    如果这个解决方案不够准确,您应该查看 multiprocessing 包。 https://docs.python.org/3.3/library/multiprocessing.html

    编辑:嗯,为了真正让它们同时启动,你不能像那样依次启动它们。您需要使用多处理,创建两个线程,然后创建某种中断来同时启动两个线程。而且我认为即使那样你也不能真正确定它们会同时启动,因为操作系统可以切换其他东西(多任务处理),即使处理器本身一切正常,事情可能会以不同的方式重新排序,不同的代码可能被缓存等。在桌面上,您永远无法保证两个程序同时启动。因此,问题就变成了它们是否一致地同时足以满足您的目的。要回答这个问题,您需要找有这方面经验的人,或者只进行一些测试。

    【讨论】:

    • 感谢您的回答。我是否正确,通过使用多处理包,我可以确保进程同时启动?
    【解决方案2】:

    我会首先启动录音线程,并在麦克风捕获的信号中寻找第一个峰值。这将告诉您在录音开始后多少毫秒检测到第一个声音。为此,您可能需要知道麦克风等的采样率 - here 是一个很好的起点。

    时间线是这样的

    ---- 录音开始 -------- 播放开始 -------- 首先检测到声音 ----

    您想知道在开始录制声音后多少毫秒被拾取(下面代码中的(first_peak - recording_start)),然后减去开始播放所花费的时间(下面的(playback_start - recording_start)

    这是一个粗略的代码大纲

    from datetime import datetime
    
    recording_start, playback_start, first_peak = None, None, None
    
    def play_sound():
        nonlocal playback_start
        playback_start = datetime.now()
    
    def record():
        nonlocal recording_start, first_peak
        recording_start = datetime.now()
        first_peak = find_peak_location_in_ms()  # implement this
    
    
    Thread(target=record()).start()  # note recording starts first
    Thread(target=play_sound()).start()
    
    # once the threads are finished
    delay = (first_peak - recording_start) - (playback_start - recording_start)
    

    PS 其他答案之一正确指出您需要担心全局解释器锁定。您可能可以通过使用 c 级 API 来录制/播放声音而不阻塞其他线程来绕过它,但您可能会发现 Python 不是该工作的正确工具

    【讨论】:

    • 感谢您的回答!是的,我已经阅读了有关全局解释器锁的信息,但是如果我正确理解了您的解决方案,那不会有问题吗?
    • 这是迄今为止最好的答案。我不认为您严格需要同时启动录音机和声音。您可以在后台有一个活动的录音机,并比较录音机首次检测到声音的时间戳和扬声器发出声音的时间。
    猜你喜欢
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 2021-11-10
    • 2012-05-01
    • 1970-01-01
    相关资源
    最近更新 更多