日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

说一说ffmpeg到处都在使用的ff_thread_once函数

發布時間:2025/3/15 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 说一说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函数的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。