[Android]JNI進階--線程池

當(dāng)一些異步的任務(wù)的時候衬廷,使用C++來創(chuàng)建線程來做任務(wù)的時候巷疼,
可以引用std::thread這個庫
使用方法如下,創(chuàng)建一個線程珊膜,里面通過std::bind來綁定方法任務(wù)容握。

std::thread thread = std::thread(std::bind(&類名::方法名,this 參數(shù));

這只是初始化線程

thread.join()

等著線程執(zhí)行完成之后,主線程才能執(zhí)行下去,此時主線程會立刻釋放子線程占用的資源

thread.detach()

主線程不需要等待子線程執(zhí)行完成车柠,主線程和子線程分離

這是簡單的線程調(diào)用剔氏,而C++中并沒封裝好線程池給我們使用。這里網(wǎng)上找了一個例子竹祷,可以簡單看看注釋谈跛。

#include <functional>
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>
#include <queue>
#include <condition_variable>
#include <future>

#ifndef THREAD_POOL_H
#define THREAD_POOL_H

namespace std {  //聲明std的作用域
#define MAX_THREAD_NUM = 256

    class MagicThreadPool {
    public:
        //內(nèi)聯(lián)函數(shù),
        inline MagicThreadPool(unsigned short size = 4) : stoped{false} {
            //線程池大小
            idlThrNum = size < 1 ? 1 : size;
            for (size = 0; size < idlThrNum; ++size) {   //初始化線程數(shù)量
                // 只有一次構(gòu)造函數(shù)塑陵,不調(diào)用拷貝構(gòu)造函數(shù)感憾,速度最快
                pool.emplace_back(
                        [this] { // 工作線程函數(shù)
                            while (!this->stoped) {
                                //聲明任務(wù)
                                std::function<void()> task;
                                {   // 獲取一個待執(zhí)行的 task
                                    std::unique_lock<std::mutex> lock{this->m_lock};// unique_lock 相比 lock_guard 的好處是:可以隨時 unlock() 和 lock()
                                    this->cv_task.wait(lock,
                                                       [this] {
                                                           return this->stoped.load() ||
                                                                  !this->tasks.empty();
                                                       }
                                    ); // wait 直到有 task
                                    if (this->stoped && this->tasks.empty())
                                        return false;
                                    task = std::move(this->tasks.front()); // 取一個 task
                                    this->tasks.pop();
                                }
                                idlThrNum--;
                                //運行任務(wù)
                                task();
                                idlThrNum++;
                            }
                        }
                );
            }
        }
        //析構(gòu)函數(shù)
        inline ~MagicThreadPool() {
            //停止全部任務(wù)
            stoped.store(true);
            cv_task.notify_all(); // 喚醒所有線程執(zhí)行
            for (std::thread &thread : pool) {
                //thread.detach(); // 讓線程“自生自滅”
                if (thread.joinable())
                    thread.join(); // 等待任務(wù)結(jié)束, 前提:線程一定會執(zhí)行完
            }
        }

        //模板令花,需要聲明類的類型阻桅,自動匹配返回值
        template<class F, class... Args>
        auto commit(F &&f, Args &&... args) -> std::future<decltype(f(args...))> {
            //直接停止任務(wù)
            if (stoped.load())    // stop == true ??
                throw std::runtime_error("commit on ThreadPool is stopped.");
            
            using RetType = decltype(f(
                    args...)); // typename std::result_of<F(Args...)>::type, 函數(shù) f 的返回值類型
            //自動返回值
            auto task = std::make_shared<std::packaged_task<RetType()> >(
                    std::bind(std::forward<F>(f), std::forward<Args>(args)...)
            );    // wtf !
            std::future<RetType> future = task->get_future();
            {    // 添加任務(wù)到隊列
                std::lock_guard<std::mutex> lock{
                        m_lock};//對當(dāng)前塊的語句加鎖  lock_guard 是 mutex 的 stack 封裝類,構(gòu)造的時候 lock()兼都,析構(gòu)的時候 unlock()
                tasks.emplace( //放入任務(wù)到任務(wù)池
                        [task]() { // push(Task{...})
                            (*task)();
                        }
                );
            }
            cv_task.notify_one(); // 喚醒一個線程執(zhí)行

            return future;
        };

        //空閑線程數(shù)量
        int idlCount() { return idlThrNum; }

    private:
        using Task = std::function<void()>;
        //線程池
        std::vector<std::thread> pool;
        //任務(wù)隊列
        std::queue<Task> tasks;
        //同步鎖
        std::mutex m_lock;
        std::condition_variable cv_task;
        std::atomic<bool> stoped;
        std::atomic<int> idlThrNum;
    };
}
#endif

使用方式嫂沉,這類方法需要聲明為static調(diào)用的方法

pool->commit(類名::方法名,參數(shù));

這里注意一定不要這里是一個MagicThreadPool.h文件扮碧,千萬別想因為代碼好看分成兩個h和cpp來寫趟章。
因為cpp將會編譯好的代碼,是無法更改的,無法進行模板在線程調(diào)用方法中的參數(shù)推導(dǎo)尤揣。會無法編譯通過搔啊。
如果想看具體的流程可以看我MagicCamera3的代碼
地址是MagicCamera3 https://github.com/cangwang/MagicCamera3,歡迎大家下載和點贊柬祠,如果有問題北戏,也可以進我的組件化群1和群2,來討論問題漫蛔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嗜愈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子莽龟,更是在濱河造成了極大的恐慌蠕嫁,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毯盈,死亡現(xiàn)場離奇詭異剃毒,居然都是意外死亡,警方通過查閱死者的電腦和手機搂赋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門赘阀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脑奠,你說我怎么就攤上這事基公。” “怎么了宋欺?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵轰豆,是天一觀的道長。 經(jīng)常有香客問我齿诞,道長酸休,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任祷杈,我火速辦了婚禮雨席,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吠式。我一直安慰自己陡厘,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布特占。 她就那樣靜靜地躺著糙置,像睡著了一般。 火紅的嫁衣襯著肌膚如雪是目。 梳的紋絲不亂的頭發(fā)上谤饭,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機與錄音,去河邊找鬼揉抵。 笑死亡容,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的冤今。 我是一名探鬼主播闺兢,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼戏罢!你這毒婦竟也來了屋谭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤龟糕,失蹤者是張志新(化名)和其女友劉穎桐磁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讲岁,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡我擂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缓艳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片校摩。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖郎任,靈堂內(nèi)的尸體忽然破棺而出秧耗,到底是詐尸還是另有隱情,我是刑警寧澤舶治,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布分井,位于F島的核電站,受9級特大地震影響霉猛,放射性物質(zhì)發(fā)生泄漏尺锚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一惜浅、第九天 我趴在偏房一處隱蔽的房頂上張望瘫辩。 院中可真熱鬧,春花似錦坛悉、人聲如沸伐厌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挣轨。三九已至,卻和暖如春轩猩,著一層夾襖步出監(jiān)牢的瞬間卷扮,已是汗流浹背荡澎。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晤锹,地道東北人摩幔。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像鞭铆,于是被迫代替她去往敵國和親或衡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

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