29_SDL 多線程與鎖機(jī)制

一、簡介

為什么要用多線程讽膏?在音視頻領(lǐng)域主要是實(shí)現(xiàn)音視頻同步桨醋。實(shí)現(xiàn)了音視頻同步棚瘟,我們的播放器就基本上合格了。
多線程的好處主要是能使程序更加充分利用硬件(主要是CPU)的性能喜最。但是也存在相應(yīng)的隱患偎蘸,如果多線程管理不好,會(huì)出現(xiàn)協(xié)調(diào)問題瞬内。

這里我們將講解一下SDL的多線程與鎖機(jī)制迷雪。

引進(jìn)的機(jī)制:線程的互斥與同步

  • 互斥:同一個(gè)資源在一定時(shí)間內(nèi)只能由一個(gè)方法訪問。
  • 同步:一個(gè)方法完成后的內(nèi)容需要同步到其他的方法虫蝶,在由其他方法操作完成后的內(nèi)容章咧。
  • 鎖與信號(hào)量
  • 鎖用于完成互斥;信號(hào)量用于同步能真。
  • 鎖的種類:讀寫鎖赁严、自旋鎖、可重入鎖粉铐。
SDL線程創(chuàng)建:SDL_CreateThread 

SDL線程等待:SDL_WaitThead

SDL互斥鎖:SDL_CreateMutex / SDL_DestroyMutex

SDL鎖定互斥:SDL_LockMutex / SDL_UnlockMutex

SDL 條件變量(信號(hào)量):SDL_CreateCond / SDL_DestoryCond

SDL 條件變量(信號(hào)量)等待 / 通知 :SDL_CondWait / SDL_CondSingal

二疼约、代碼實(shí)現(xiàn):

我們通過SDL的鎖機(jī)制實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者

2.1、聲明

//mainwindow.h

Ui::MainWindow *ui;
/** 互斥鎖*/
SDL_mutex *_mutex = nullptr;
/** 條件變量:消費(fèi)者等待蝙泼,生產(chǎn)者喚醒 */
SDL_cond *_cond = nullptr;

std::list<QString> *_list = nullptr;
int _index = 0;

void consume(QString name);
void produce(QString name);

2.2程剥、創(chuàng)建鎖、消費(fèi)者

//mainwindow.cpp

// 創(chuàng)建互斥鎖
 _mutex = SDL_CreateMutex();
// 創(chuàng)建條件變量
_cond = SDL_CreateCond();

// 創(chuàng)建鏈表
_list = new std::list<QString>();

// 創(chuàng)建消費(fèi)者
consume("消費(fèi)者1");
consume("消費(fèi)者2");
consume("消費(fèi)者3");
consume("消費(fèi)者4");

2.3汤踏、銷毀

MainWindow::~MainWindow(){
    delete ui;
    delete _list;
    SDL_DestroyMutex(_mutex);
    SDL_DestroyCond(_cond);
}

2.4织鲸、實(shí)現(xiàn)生產(chǎn)者邏輯

void MainWindow::produce(QString name){
    std::thread([this,name](){
        SDL_LockMutex(_mutex);

        qDebug() << name << "開始生產(chǎn)";

        _list->push_back(QString("%1").arg(++_index));
        _list->push_back(QString("%1").arg(++_index));
        _list->push_back(QString("%1").arg(++_index));

        // 喚醒消費(fèi)者:趕緊開始消費(fèi)
        SDL_CondSignal(_cond);

        SDL_UnlockMutex(_mutex);
    }).detach();
}

2.5、實(shí)現(xiàn)銷毀者邏輯

void MainWindow::consume(QString name){
    std::thread([this,name](){
        SDL_LockMutex(_mutex);
        while (true) {
            qDebug() << name << "開始消費(fèi)";
            while (!_list->empty()) {
                qDebug() << _list->front();
                // 刪除頭部
                _list->pop_front();
                // 睡眠500ms
                std::this_thread::sleep_for(std::chrono::milliseconds(500));
            }
            /**
             * 1.釋放互斥鎖
             * 2.等待條件_cond
             * 3.等到了條件_cond茎活、加鎖
             */
            SDL_CondWait(_cond,_mutex);
        }
        SDL_UnlockMutex(_mutex);
    }).detach();
}

2.6昙沦、創(chuàng)建生產(chǎn)者

void MainWindow::on_produceBtn_clicked(){
    // 創(chuàng)建生產(chǎn)者
    produce("生產(chǎn)者1");
    produce("生產(chǎn)者2");
    produce("生產(chǎn)者3");
}

三、分裝SDL鎖機(jī)制

我們可以將SDL的鎖機(jī)制的api進(jìn)行二度分裝载荔,以便后面的音視頻使用

condmutex.h

#ifndef CONDMUTEX_H
#define CONDMUTEX_H

#include <SDL2/SDL.h>


class CondMutex {
public:
    CondMutex();
    ~CondMutex();

    void lock();
    void unlock();
    void signal();
    void broadcast();
    void wait();

private:
    /** 互斥鎖 */
    SDL_mutex *_mutex = nullptr;
    /** 條件變量 */
    SDL_cond *_cond = nullptr;
};

#endif // CONDMUTEX_H

condmutex.cpp

#include "condmutex.h"

CondMutex::CondMutex(){
    // 創(chuàng)建互斥鎖
    _mutex = SDL_CreateMutex();
    // 創(chuàng)建條件變量
    _cond = SDL_CreateCond();
}

CondMutex::~CondMutex(){
    SDL_DestroyMutex(_mutex);
    SDL_DestroyCond(_cond);
}

void CondMutex::lock(){
    SDL_LockMutex(_mutex);
}

void CondMutex::unlock(){
    SDL_UnlockMutex(_mutex);
}

void CondMutex::signal(){
    SDL_CondSignal(_cond);
}

void CondMutex::broadcast(){
    SDL_CondBroadcast(_cond);
}

void CondMutex::wait(){
    SDL_CondWait(_cond,_mutex);
}

代碼鏈接1
代碼鏈接2

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盾饮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌丘损,老刑警劉巖普办,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異徘钥,居然都是意外死亡衔蹲,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門呈础,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舆驶,“玉大人,你說我怎么就攤上這事而钞∩沉” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵臼节,是天一觀的道長撬陵。 經(jīng)常有香客問我,道長网缝,這世上最難降的妖魔是什么巨税? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮粉臊,結(jié)果婚禮上草添,老公的妹妹穿的比我還像新娘。我一直安慰自己维费,他們只是感情好果元,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著犀盟,像睡著了一般而晒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阅畴,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天倡怎,我揣著相機(jī)與錄音,去河邊找鬼贱枣。 笑死监署,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纽哥。 我是一名探鬼主播钠乏,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼春塌!你這毒婦竟也來了晓避?” 一聲冷哼從身側(cè)響起簇捍,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎俏拱,沒想到半個(gè)月后暑塑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锅必,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年事格,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搞隐。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驹愚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尔许,到底是詐尸還是另有隱情么鹤,我是刑警寧澤终娃,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布味廊,位于F島的核電站,受9級(jí)特大地震影響棠耕,放射性物質(zhì)發(fā)生泄漏余佛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一窍荧、第九天 我趴在偏房一處隱蔽的房頂上張望辉巡。 院中可真熱鬧,春花似錦蕊退、人聲如沸郊楣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽净蚤。三九已至,卻和暖如春输硝,著一層夾襖步出監(jiān)牢的瞬間今瀑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來泰國打工点把, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留橘荠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓郎逃,卻偏偏與公主長得像哥童,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子褒翰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容