日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 说一说ffmpeg到处都在使用的ff_thread_once函数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從名字就能知道ff_thread_once函數(shù)的作用,就是保證在多線(xiàn)程調(diào)用的時(shí)候,函數(shù)只執(zhí)行一次

FFmpeg中是使用經(jīng)典的double check來(lái)保證函數(shù)只執(zhí)行一次的,我們來(lái)跟蹤下函數(shù)看下具體的實(shí)現(xiàn):
ff_thread_once函數(shù)是調(diào)用pthread_once函數(shù)實(shí)現(xiàn)的:

#define ff_thread_once(control, routine) pthread_once(control, routine)

pthread_once函數(shù)實(shí)現(xiàn)如下:

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; }


可以看到代碼中有兩處對(duì)done是否為1進(jìn)行檢查的地方,很多人剛開(kāi)始看到這個(gè)代碼可能感到很奇怪,為什么同樣的值要檢查兩次,其實(shí)這就是double check的實(shí)現(xiàn)。
假設(shè)現(xiàn)在多個(gè)線(xiàn)程同時(shí)調(diào)用函數(shù) pthread_once,這個(gè)時(shí)候第一個(gè)先執(zhí)行的先檢查done是否為1,為0的時(shí)候在獲取鎖,獲取鎖成功了在檢查一次done是否為0,只有這時(shí)還是為0的時(shí)候才調(diào)用函數(shù), 這樣就能保證只有一個(gè)線(xiàn)程能執(zhí)行到init_routine函數(shù)。連個(gè)檢查缺一不可。

  • 假設(shè)缺少1,
    第一個(gè)線(xiàn)程獲取到鎖之后,在執(zhí)行done是否為0的檢查時(shí),第二個(gè)線(xiàn)程會(huì)在獲取鎖的地方死等,直到上一個(gè)線(xiàn)程執(zhí)行結(jié)束釋放鎖之后,第二個(gè)線(xiàn)程才能獲取到鎖,然后檢查done已經(jīng)為1,就釋放鎖退出,雖然這樣能保證函數(shù)init_routine()只執(zhí)行了一次,但是由于每個(gè)調(diào)用pthread_once的函數(shù)都得獲取一次鎖,存在競(jìng)爭(zhēng)的時(shí)候還得等待,這樣在成千上萬(wàn)的線(xiàn)程的服務(wù)器中,是不能接受的。加上1就能解決這個(gè)問(wèn)題
  • 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; }
  • 假設(shè)缺少2
    在第一個(gè)線(xiàn)程檢車(chē)到done為0,然后獲取到鎖,線(xiàn)程1的時(shí)間片結(jié)束,內(nèi)核將執(zhí)行權(quán)交給線(xiàn)程2,線(xiàn)程2檢查done為0,然后獲取鎖,因?yàn)榫€(xiàn)程1已經(jīng)拿到鎖了,所以線(xiàn)程2就主動(dòng)丟掉執(zhí)行權(quán),將執(zhí)行權(quán)交出,線(xiàn)程1執(zhí)行結(jié)束之后釋放鎖, 這個(gè)時(shí)候線(xiàn)程2拿到鎖,因?yàn)闆](méi)有標(biāo)號(hào)2的檢查,所有也調(diào)用了一次init_routine(), 這樣就和設(shè)計(jì)的初衷相違背了。
  • 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; }

    總結(jié)

    以上是生活随笔為你收集整理的说一说ffmpeg到处都在使用的ff_thread_once函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。