A Basic Example of Threads Synchronization in Python, python中的线程同步示例

本文介绍如何使用Python的threading模块中的Event对象来实现多线程间的精确同步。通过一个播放视频和音频同步的例子,展示了如何确保两个并行运行的函数能够同时启动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://zulko.github.io/blog/2013/09/19/a-basic-example-of-threads-synchronization-in-python/

 

 

We will see how to use threading Events to have functions in different Python threads start at the same time.

I recently coded a method to view movies in Python : it plays the video, and in the same time, in a parralel thread, it renders the audio. The difficult part is that the audio and video should be exactly synchronized. The pseudo-code looks like this:

1
2
3
4
def view(movie):   new_thread( play_audio( movie ) )  play_video( movie ) 

In this code, play_audio() and play_video() will start at approximately the same time and will run parallely, but these functions need some preparation before actually starting playing stuff. Their code looks like that:

1
2
3
4
5
6 7 8 9 10 
def play_audio(movie):   audio = prepare_audio( movie )  audio.start_playing()   def play_video(movie):   video = prepare_video( movie )  video.start_playing() 

To have a well-synchronized movie we need the internal functions audio.start_playing() and video.start_playing(), which are run in two separate threads, to start at exactly the same time. How do we do that ?

The solution seems to be using threading.Event objects. An Event is an object that can be accessed from all the threads and allows very basic communication between them : each thread can set or unset an Event, or check whether this event has already been been set (by another thread).

For our problem we will use two events video_ready and audio_ready which will enable our two threads to scream at each other “I am ready ! Are you ?”. Here is the Python fot that:

1
2
3
4
5
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 
import threading

def play_audio(movie, audio_ready, video_ready):   audio = prepare_audio( movie )   audio_ready.set() # Say "I'm ready" to play_video()  video_ready.wait() # Wait for play_video() to say "I'm ready"   audio.start_playing()   def play_video(movie, audio_ready, video_ready):   video = prepare_video( movie )   video_ready.set() # Say "I'm ready" to play_audio()  audio_ready.wait() # Wait for play_audio() to say "I'm ready"   video.start_playing() 

and finally the code for view(movie):

1
2
3
4
5
6 7 8 9 10 11 12 
def view(movie):   audio_ready = threading.Event()  video_ready = threading.Event()    # launch the parrallel audio thread  audiothread = threading.Thread(target=play_audio,  args = (movie, audio_ready, video_ready))  audiothread.start()   play_video(movie, audio_ready, video_ready) 

A few tips tips to go further:

  • Here I am using the module threading, and the two threads will be played in parrallel on the same processor. If you have a computer with several processors you can also use the multiprocessing module to have your threads played on two different processors (which can be MUCH faster). Nicely enough the two modules have the same syntax: simply replace threading by multiprocessing and Thread by Process in the example above and it should work.
  • In my original program, I also use an Event to terminate play_video and play_audio at the same time: when the video playing is exited, play_video unsets that Event. In play_audio, this event is regularly checked, and when it is seen to be unset, play_audio exits too.
  • Instead of using wait to wait for an Event to be set, you can use a loop to you decide at which frequency you want to check the Event. Only do that if don’t mind a lag of a few milliseconds between your processes :
1
2
3
import time
while not audio_ready.is_set():  time.sleep(0.002) # sleep 2 milliseconds 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值