说一说ffmpeg到处都在使用的ff_thread_once函数
生活随笔
收集整理的這篇文章主要介紹了
说一说ffmpeg到处都在使用的ff_thread_once函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
從名字就能知道ff_thread_once函數的作用,就是保證在多線程調用的時候,函數只執行一次
FFmpeg中是使用經典的double check來保證函數只執行一次的,我們來跟蹤下函數看下具體的實現:
ff_thread_once函數是調用pthread_once函數實現的:
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函數。連個檢查缺一不可。
第一個線程獲取到鎖之后,在執行done是否為0的檢查時,第二個線程會在獲取鎖的地方死等,直到上一個線程執行結束釋放鎖之后,第二個線程才能獲取到鎖,然后檢查done已經為1,就釋放鎖退出,雖然這樣能保證函數init_routine()只執行了一次,但是由于每個調用pthread_once的函數都得獲取一次鎖,存在競爭的時候還得等待,這樣在成千上萬的線程的服務器中,是不能接受的。加上1就能解決這個問題
在第一個線程檢車到done為0,然后獲取到鎖,線程1的時間片結束,內核將執行權交給線程2,線程2檢查done為0,然后獲取鎖,因為線程1已經拿到鎖了,所以線程2就主動丟掉執行權,將執行權交出,線程1執行結束之后釋放鎖, 這個時候線程2拿到鎖,因為沒有標號2的檢查,所有也調用了一次init_routine(), 這樣就和設計的初衷相違背了。
總結
以上是生活随笔為你收集整理的说一说ffmpeg到处都在使用的ff_thread_once函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 作者:刘诗凯(1983-),男,华为大数
- 下一篇: 作者:吴甘沙,男,现任英特尔中国研究院院