一、模板類queue,包含頭文件<queue>中,是一個FIFO隊列。ios
queue.push():在隊列尾巴增長數據
queue.pop():移除隊列頭部數據
queue.font():獲取隊列頭部數據的引用
...
二、Qt庫的線程池,QThreadPool安全
QThreadPool.setMaxThreadCount():設置線程池最大線程數 QThreadPool.start(new QRunnable(..)):開啓線程池調用QRunnable
三、QRunnable執行任務函數
void run();//重寫虛函數,在裏面消費任務隊列 setAutoDelete(true)//默認就是true,消費結束自動回收內存
四、代碼this
run.hspa
#ifndef RUN_H #define RUN_H #include <QObject> #include <QRunnable> #include <string> #include <iostream> struct MyString { std::string valueStr; }; class Run : public QObject , public QRunnable { Q_OBJECT public: Run() = default; Run(const MyString& myString); protected: ~Run() = default; void run(); signals: public slots: private: MyString myString; }; #endif // RUN_H
說明:MyString結構體代替實際項目中的任務,Run接口的run純虛函數用來消費分配來的MyString
run.cpp
#include "run.h" #include <QThread> #include <QDebug> Run::Run(const MyString &myString) { this->myString = myString; //this->setAutoDelete(true);//默認就是true } void Run::run() { //std::cout << "value:" << this->myString.valueStr <<";調用線程ID爲:" << QThread::currentThread() << std::endl; qDebug() << "value:" << QString::fromStdString(myString.valueStr) << "thread:" << QThread::currentThreadId(); QThread::msleep(100); }
說明:不使用cout打印是由於,cout打印不是原子操做,可能多個字符串被雜糅在一塊兒打印;qDebug不會,應該底層加了鎖
main.cpp線程
#include <QCoreApplication> #include "run.h" #include <queue> #include <mutex> #include <QThreadPool> #include <thread> using namespace std; queue<MyString> myList; mutex myMutex; volatile bool addThreadIsEnd = false; void makeListThread(); int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); cout << "begin main" << endl; thread addThread(makeListThread); addThread.detach(); cout << "begin addThread" << endl; QThreadPool tp; tp.setMaxThreadCount(20); cout << "begin threadPool" << endl; while(true) { if(!myList.empty()) { MyString tempMyString = myList.front(); tp.start(new Run(tempMyString)); myMutex.lock(); myList.pop(); myMutex.unlock(); } else { if(addThreadIsEnd) { break; } else { QThread::msleep(10); } } } cout << "end main,list size:" << myList.size() << endl; return a.exec(); } void makeListThread() { string a; MyString tempMyString; for(int i=0;i<10000;i++) { QThread::msleep(0); a = to_string(i); tempMyString.valueStr = a; myMutex.lock(); myList.push(tempMyString); myMutex.unlock(); } addThreadIsEnd = true; cout << "end addThread" << endl; }
五、模型

六、其餘說明指針
6.一、假設線程池大小有n個,那麼這n個線程在線程池初始化的時候就已經定了,即n個線程id是恆定的,隊列永遠由這n個線程消費code
6.二、std::queue非線程安全,同時往隊列加任務、取任務可能會觸發線程安全問題;同時刪除頭任務、訪問頭任務也可能會觸發線程安全問題,須要加線程鎖對象
6.三、tp.start(new Run(tempMyString));這裏new了一個沒有指針指向的Runnable對象,在哪裏回收的呢?Run.setAutoDelete(true)自動回收blog