说一说ffmpeg到处都在使用的ff_thread_once函数
从名字就能知道ff_thread_once
函数的作用,就是保证在多线程调用的时候,函数只执行一次
FFmpeg
中是使用经典的double check
来保证函数只执行一次的,我们来跟踪下函数看下具体的实现:
ff_thread_once函数是调用pthread_once函数实现的:
#define ff_thread_once(control, routine) pthread_once(control, routine)
pthread_once函数实现如下:
static av_always_inline int pthread_once(pthread_once_t *once_control,void (*init_routine)(void))
{if (!once_control->done){_fmutex_request(&once_control->mtx, 0);if (!once_control->done){init_routine();once_control->done = 1;}_fmutex_release(&once_control->mtx);}return 0;
}
可以看到代码中有两处对done是否为1进行检查的地方,很多人刚开始看到这个代码可能感到很奇怪,为什么同样的值要检查两次,其实这就是double check的实现。
假设现在多个线程同时调用函数 pthread_once,这个时候第一个先执行的先检查done是否为1,为0的时候在获取锁,获取锁成功了在检查一次done是否为0,只有这时还是为0的时候才调用函数, 这样就能保证只有一个线程能执行到init_routine函数。连个检查缺一不可。
- 假设缺少1,
第一个线程获取到锁之后,在执行done是否为0的检查时,第二个线程会在获取锁的地方死等,直到上一个线程执行结束释放锁之后,第二个线程才能获取到锁,然后检查done已经为1,就释放锁退出,虽然这样能保证函数init_routine()只执行了一次,但是由于每个调用pthread_once的函数都得获取一次锁,存在竞争的时候还得等待,这样在成千上万的线程的服务器中,是不能接受的。加上1就能解决这个问题
static av_always_inline int pthread_once(pthread_once_t *once_control,void (*init_routine)(void))
{_fmutex_request(&once_control->mtx, 0);if (!once_control->done){init_routine();once_control->done = 1;}_fmutex_release(&once_control->mtx);return 0;
}
- 假设缺少2
在第一个线程检车到done为0,然后获取到锁,线程1的时间片结束,内核将执行权交给线程2,线程2检查done为0,然后获取锁,因为线程1已经拿到锁了,所以线程2就主动丢掉执行权,将执行权交出,线程1执行结束之后释放锁, 这个时候线程2拿到锁,因为没有标号2的检查,所有也调用了一次init_routine(), 这样就和设计的初衷相违背了。
static av_always_inline int pthread_once(pthread_once_t *once_control,void (*init_routine)(void))
{if (!once_control->done){_fmutex_request(&once_control->mtx, 0);init_routine();once_control->done = 1;_fmutex_release(&once_control->mtx);}return 0;
}
说一说ffmpeg到处都在使用的ff_thread_once函数相关推荐
- 宜信创始人唐宁:技术到处都是,关键看怎么用
宜信创始人唐宁:技术到处都是,关键看怎么用 极客公园 2017-06-02 16:15 阅读:4443 摘要:作者:「痛点是什么?」5月26日下午的北大斯坦福中心,这是宜信创始人唐宁口中出现频率 ...
- 最近大街上,到处都是X团的地推
小文说,最近大街上,到处都是X团的地推,成群结队的,拉着每一个路人推销他们的软件,忽悠着你下载他们的APP. 小文昨天中午出去吃饭,五.六个X团的地推,把一个漂亮女孩围在中间,各个都是轻佻的语气,拜托 ...
- 不要到处都用@Autowired啦
相信大部分人项目只要用了spring框架,肯定到处都是@Autowired. 注意: spring4.3以后就可以省略@Autowired了,全部更新内容: 地址:其中跟新内容如下 这是什么意思呢,翻 ...
- 小学生python-小学生都能学会的python(函数)
小学生都能学会的python(函数) 神马是函数 函数: 对功能或者动作的封装 函数的定义 def 函数名(形参列表): 函数体(return) ret = 函数名(实参列表) 函数的返回值 retu ...
- 【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )
文章目录 I . FFMPEG 交叉编译后的函数库及头文件 II . FFMPEG 静态库打包动态库 ( 仅做参考 ) III . 创建 Android Studio 工程 IV . FFMPEG 头 ...
- 小学生在家自学python_小学生都能学会的python(函数)
小学生都能学会的python(函数) 神马是函数 函数: 对功能或者动作的封装 函数的定义 def 函数名(形参列表): 函数体(return) ret = 函数名(实参列表) 函数的返回值 retu ...
- c语言中ch1和ch2是什么意思,2020-05-26(C语言)1.将串str中所有值为ch1的字符转换成ch2的字符,如果str为空串,或者串中不含值为ch1的字符,则什么都不做.2.逆转函数...
//1.将串str中所有值为ch1的字符转换成ch2的字符,如果str为空串,或者串中不含值为ch1的字符,则什么都不做.2.逆转函数 include include define MAXLEN 25 ...
- 我对NHibernate的感受(2):何必到处都virtual
上一篇主要是在夸NHibernate实现的好,而这篇就完全是来抱怨的了.NHiberante有个毛病,就是如果是和数据库产生映射的类,就要求所有的public成员和protected成员必须是virt ...
- NHibernate :何必到处都virtual
上一篇文章主要是在夸NHibernate实现的好,而这篇就完全是来抱怨的了.NHiberante有个毛病,就是如果是和数据库产生映射的类,就要求所有的public成员和protected成员必须是vi ...
最新文章
- php 正则中文匹配
- jsp 环境配置记录
- python getattr_python __getattr__ 巧妙应用
- 五花八门的bug跟踪工具
- JVM 垃圾回收算法及回收器详解
- SDNU 1423.入学考试(01背包)
- 借助HiddenText 确定CheckBoxList当前的操作类型及点击的CheckBox
- 十大因素——造就优秀的董事长
- 要学会“收”和“放”
- 基于Java的对称加密算法和非对称加密算法
- 求职面试过程中都需要注意哪些
- app 播放服务器文件,配置apple-app-site-association文件并在服务器上传
- Debian10上使用360随身Wifi
- 教你看懂ACC、TJA、 ICA、ICC 这些功能都能干些啥
- TransOMCS:从语言图提取常识知识
- java频繁的读写文件_大量较为频繁读写的文件一般如何进行存储?
- 工信部通报下架60款APP:关联有赞、三六零、唯品会等上市公司
- 国内做数据可视化大屏哪家强?这5款产品你必须了解
- 守护进程--day33
- springboot+flowable请假详细流程