简体   繁体   English

如何同步python线程的启动时间?

[英]How to synchronize the start time of python threads?

I want to measure the time delay of a signal.我想测量信号的时间延迟。 To do that the signal is put on a speaker an the delay when it gets captured by a microphone is estimated.为此,将信号放在扬声器上,并估计它被麦克风捕获时的延迟。 The delay is expected to be in the range of milliseconds, so it is crucial to start the speaker signal and the measurement at the exact same time.延迟预计在毫秒范围内,因此在完全相同的时间启动扬声器信号和测量至关重要。

My question is if that can be achieved by using threads:我的问题是是否可以通过使用线程来实现:

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()

or is there a better way to d it?或者有更好的方法吗?

I would start the recording thread first and look for the first peak in the signal captured by the mic.我会首先启动录音线程并寻找麦克风捕获的信号中的第一个峰值。 This will tell you how many ms after recording started the first sound was detected.这将告诉您录制开始后多少毫秒检测到第一个声音。 For this you probably need to know the sampling rate of the mic etc- here is a good starting point.为此,您可能需要知道麦克风等的采样率 - 是一个很好的起点。

The timeline is something like this时间线是这样的

---- recording start ------- playback start -------- sound first detected ----

You want to find out how many ms after you start recording a sound was picked up ( (first_peak - recording_start) in the code below), and then subtract the time it took to start the playback ( (playback_start - recording_start) below)您想知道在开始录制声音后多少毫秒被拾取(下面代码中的(first_peak - recording_start) ),然后减去开始播放所花费的时间(playback_start - recording_start)下面的(playback_start - recording_start)

Here's a rough code outline这是一个粗略的代码大纲

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 one of the other answers correctly points out that you need to worry about the global interpreter lock. PS 其他答案之一正确指出您需要担心全局解释器锁定。 You can likely bypass it by using c-level APIs to record/play the sound without blocking other threads, but you may find Python's not the right tool for that job您可以通过使用 c 级 API 来记录/播放声音而不阻塞其他线程来绕过它,但是您可能会发现 Python 不是该工作的正确工具

It won't be 100% concurrent real-time, but no solution for desktop will ever be.它不会是 100% 并发实时,但桌面解决方案永远不会。 The question then becomes if it is accurate enough for your application.那么问题就变成了它对于您的应用程序是否足够准确。 To know this you should simply run a few tests with known delays and see if it works.要知道这一点,您应该简单地运行一些已知延迟的测试,看看它是否有效。

You should know about the global interpreter lock: https://docs.python.org/3.3/glossary.html#term-global-interpreter-lock .您应该了解全局解释器锁: https : //docs.python.org/3.3/glossary.html#term-global-interpreter-lock This means that even on a multicore pc you code won't run truly concurrent.这意味着即使在多核 PC 上,您的代码也不会真正并发运行。

If this solution is not accurate enough, you should look into the multiprocessing package.如果此解决方案不够准确,您应该查看 multiprocessing 包。 https://docs.python.org/3.3/library/multiprocessing.html https://docs.python.org/3.3/library/multiprocessing.html

Edit: Well, in order to truly get them to start simultaneously you can't start them sequentially after each other like that.编辑:嗯,为了真正让它们同时启动,你不能像这样一个接一个地依次启动它们。 You need to use multiprocessing, create the two threads, and then create some kind of interrupt that will start the two threads at the same time.您需要使用多处理,创建两个线程,然后创建某种可以同时启动两个线程的中断。 And I think even then you can't be truly sure they will start at the same time because the OS can switch in other stuff (multitasking), and even if that goes fine in the processors itself things might be reordered differently, different code might be cached, etc. On a desktop you can never have the guarantuee that two programs start simultaneously.而且我认为即使那样你也不能真正确定它们会同时启动,因为操作系统可以切换其他东西(多任务处理),即使处理器本身没问题,事情可能会以不同的方式重新排序,不同的代码可能被缓存等。在桌面上,您永远无法保证两个程序同时启动。 So the question then becomes if they are consistently simultaneous enough for your purpose.因此,问题就变成了它们是否一致地同时满足您的目的。 To answer that you will need to find someone with experience in this, or just run a few tests.要回答这个问题,您需要找到有这方面经验的人,或者只进行一些测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM