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

Posted by Zulko Sep 19th, 2013 MoviePy, Python,, threads,

A Basic Example of Threads Synchronization in Python, python中的线程同步示例的更多相关文章

  1. Python程序中的线程操作(线程池)-concurrent模块

    目录 Python程序中的线程操作(线程池)-concurrent模块 一.Python标准模块--concurrent.futures 二.介绍 三.基本方法 四.ProcessPoolExecut ...

  2. Python并发编程-进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  3. 30、Python程序中的线程操作(oncurrent模块)

    进程是cpu资源分配的最小单元,一个进程中可以有多个线程. 线程是cpu计算的最小单元. 对于Python来说他的进程和线程和其他语言有差异,是有GIL锁. GIL锁 GIL锁保证一个进程中同一时刻只 ...

  4. Python程序中的线程操作-锁

    目录 一.同步锁 1.1 多个线程抢占资源的情况 1.1.1 对公共数据的操作 1.2 同步锁的引用 1.3 互斥锁与join的区别 二.死锁与递归锁 2.1 死锁 2.2 递归锁RLock 三.典型 ...

  5. Python程序中的线程操作-concurrent模块

    目录 一.Python标准模块--concurrent.futures 二.介绍 三.基本方法 四.ProcessPoolExecutor 五.ThreadPoolExecutor 六.map的用法 ...

  6. Python程序中的线程操作-创建多线程

    目录 一.python线程模块的选择 二.threading模块 三.通过threading.Thread类创建线程 3.1 创建线程的方式一 3.2 创建线程的方式二 四.多线程与多进程 4.1 p ...

  7. Python程序中的线程操作-线程队列

    目录 一.线程队列 二.先进先出 三.后进先出 四.存储数据时可设置优先级的队列 4.1 优先级队列 4.2 更多方法说明 一.线程队列 queue队列:使用import queue,用法与进程Que ...

  8. [b0032] python 归纳 (十七)_线程同步_信号量Semaphore

    代码: # -*- coding: utf-8 -*- """ 多线程并发同步 ,使用信号量threading.Semaphore 逻辑: 多个线程,对同一个共享变量 , ...

  9. Python程序中的线程操作-守护线程

    目录 一.守护线程 1.1 详细解释 1.2 守护线程例1 1.3 守护线程例2 一.守护线程 无论是进程还是线程,都遵循:守护xx会等待主xx运行完毕后被销毁.需要强调的是:运行完毕并非终止运行. ...

随机推荐

  1. catch(…) vs catch(CException *)?

    转自:https://stackoverflow.com/questions/7412185/what-is-the-difference-between-catch-vs-catchcexcepti ...

  2. 阿里巴巴Java开发规约插件-体验

    插件有哪些功能? 阿里技术公众号于今年的2月9日首次公布<阿里巴巴Java开发规约>,瞬间引起全民代码规范的热潮,上月底又发布了PDF的终极版,大家踊跃留言,期待配套的静态扫描工具开放出来 ...

  3. 静态变量数组实现LRU算法

    LRU算法的解释详情请见 https://baike.baidu.com/item/LRU/1269842 这里百度百科给出的比较详细,然后后面有一个例子 说 LRU(least recently u ...

  4. ref 属性使用eslint报错

    react 使用 ref 报错 ,[eslint] Using string literals in ref attributes is deprecated. (react/no-string-re ...

  5. linux命令之find和locate

    1.find / -name  log.xml   按照名字查找log.xml文件 2.locate log.xml     查找log.xml文件(效率高) 3.grep 'hive'  word. ...

  6. callable()

    callable() 用于判断一个对象是否是可调用的,函数或类都可以被调用 In [1]: callable('a') Out[1]: False In [2]: def fun(): ...: pa ...

  7. 详解Integer.toString(int i)方法和String.valueOf(int i)方法

    通过查看String类的源码: public static String valueOf(int i) { return Integer.toString(i); } 我们可以看到,String.va ...

  8. PHP之命名空间

    前面的话 从广义上来说,命名空间是一种封装事物的方法.在很多地方都可以见到这种抽象概念.例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色.这个原理应用到程序设计 ...

  9. Deploying Cloud Foundry on OpenStack Juno and XenServer (Part I)

    link http://rabbitstack.github.io/deploying-cloud-foundry-on-openstack-juno-and-xenserver-part-i/ Cl ...

  10. jQuery数据缓存

    jQuery引入数据缓存机制的原因: 1.储存更DOM节点相关的数据.事件.动画等信息 2.用一种低耦合的方式让DOM节点和数据联系起来 实现原理: 1.jQuery内部创建cache对象 2.为需要 ...