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. 学习使用资源文件[11] - DLL 中的资源文件

      本例将把一张 bmp 图片, 以资源文件的方式嵌入 dll, 然后再调用. 第一步: 建一个 DLL 工程, 如图: 然后保存, 我这里使用的名称都是默认的. 第二步: 建一个资源原文件, 如图: ...

  2. VC++ 6.0开发套件(自己收藏!)

    安装镜像ISO                     VC++ 6.0_SP6_Win7企业版(中英文集成).iso MSDN安装镜像ISO                 MSDN_Oct_200 ...

  3. js判断用户关闭页面或浏览器

    <html><head><meta http-equiv="Content-Type" content="text/html; charse ...

  4. when an event of selector will be fired

    OP_READ Operation-set bit for read operations. Suppose that a selection key's interest set contains ...

  5. C#字符串二进制互换

    static void Main(string[] args)         {             string str = "宋军辉";             Cons ...

  6. 将display设置为inline-block之后产生间隙然后换行问题的解决方法

    在我们会用display的时候,inline-block肯定不陌生吧,我今天在做项目的时候,用了inline-block,使a标签可以自定义宽度,但是随之而来的问题就是换行的BUG,如下图 特地加了一 ...

  7. poj_1161 并查集

    题目大意 一个学校里面有n个学生(标号从0到n-1)和m个社团(标号从0到m-1),每个学生属于0个或多个社团.近期有SARS传播,属于同一个社团的学生的SARS可以相互传染.给出m个社团中的学生标号 ...

  8. strace命令的使用

    author: headsen  chen date: 2018-08-28   21:25:48 跟踪一个命令的过程: [root@zabbix-test ~]# yum -y install st ...

  9. application/json和application/x-www-form-urlencoded区别

    application/json和application/x-www-form-urlencoded都是表单数据发送时的编码类型. EncType: enctype 属性规定在发送到服务器之前应该如何 ...

  10. PHP 允许Ajax跨域访问 (Access-Control-Allow-Origin)

    Ajax访问php,报错 php顶部加上即可: header("Access-Control-Allow-Origin: *");