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. 国外大神说:在编程中使用If语句的潜在危险

    大多数编程语言中if语句主要有两个作用:验证输入以保护域免受错误数据的影响,以及处理域内业务逻辑.但是,Udi Dahan最近在阿姆斯特丹DDD欧洲会议上的发言中指出,我们一般很     当我们查看系 ...

  2. jquery插件大全

    241个jquery插件—jquery插件大全 免费JQuery插件 推荐12款非常有用的流行 jQuery 插件

  3. mybatise 动态sql

    1. <if><choose> 动态sql 相当 <if> Java if  满足多个条件  <choose> <when>    java ...

  4. [ACM] poj 2017 Speed Limit

    Speed Limit Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 17030   Accepted: 11950 Des ...

  5. 微信小程序 ui框架(辅助)

    WeUi: https://weui.io/ https://github.com/weui/weui-wxss/ Wa-Ui: https://github.com/liujians/Wa-UI/w ...

  6. Hash表(hash table ,又名散列表)

    直接进去主题好了. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据key而直接进行访问的数据结构.也就是说,它通过把key映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...

  7. eclispe创建gradle项目

    1.打开eclipse,选择Help——>install from Catalog,安装如图所示的gradle 2.右击空白处,new——>other——>Gradle——>G ...

  8. 【七牛云】时间戳防盗链鉴权php实现

    基于时间戳防盗链的功能其实每家的CDN都是支持的.主要是通过使用约定的加密字符串来对具有访问有效期的资源链接进行一些加密计算的到一个sign值,然后访问外链里面带上这个sign和截止时间戳去访问CDN ...

  9. 【Java nio】 NonBlocking NIO

    package com.slp.nio; import org.junit.Test; import java.io.IOException; import java.net.InetSocketAd ...

  10. outline的兼容性及使用限制

    outline 和 border的区别: outline不占据文档空间,border占据文档空间. outline无法单独设置上下左右,只要设置outline,必须所有的边都设置:border可以设置 ...