在處理大量併發任務的時候,如果按照傳統的方式,乙個請求乙個執行緒來處理請求任務,大量的執行緒建立和銷毀將消耗過多的系統資源,還增加了執行緒上下文切換的開銷,而通過執行緒池技術就可以很好的解決這些問題,執行緒池技術通過在系統中預先建立一定數量的執行緒,當任務請求到來時從執行緒池中分配乙個預先建立的執行緒去處理任務,執行緒在完成任務之後還可以重用,不會銷毀,而是等待下次任務的到來.
半同步半非同步執行緒池分為三層:
同步服務層: 它處理來自上層的任務請求,上層的請求可能是併發的,這些請求不是馬上就會被處理的,而是將這些任務放到乙個同步排隊層中,等待處理.
同步排隊層: 來自上層的任務請求都會加到排隊層中等待處理.
非同步服務層: 這一層中會有多個執行緒同時處理排隊層中的任務,非同步服務層從同步排隊層中取出任務並行的處理.
/********************************同步佇列******************************/
template
class syncqueue
//新增事件
void put(const t& x)
//新增事件
void put(t && x)
//從佇列中取事件,取所有事件
void take(std::list &list)
);if (m_needstop)
list = std::move(m_queue);
m_notfull.notify_one();
}//取乙個事件
void take(t &t)
);if (m_needstop)
t = m_queue.front();
m_queue.pop_front();
m_notfull.notify_one();
}//終止同步佇列
void stop()
//喚醒所有程序一一終止
m_notfull.notify_all();
m_notempty.notify_all();
}//隊列為空
bool empty()
//隊列為滿
bool full()
//佇列大小
size_t size()
//佇列大小
int count()
private:
//佇列不為滿
bool notfull() const
return !full;
}//佇列不為空
bool notempty() const
return !empty;
}//向佇列中新增事件,若不為滿且終止標誌為false則新增事件
template
void add(f && x)
);if (m_needstop)
m_queue.push_back(std::forward(x));
m_notempty.notify_one();
}private:
//緩衝區
std::list m_queue;
//互斥量
std::mutex m_mutex;
//佇列不為空的條件變數
std::condition_variable m_notempty;
//佇列不為滿的條件變數
std::condition_variable m_notfull;
//任務佇列最大長度
int m_maxsize;
//終止的標識,當為true時代表同步佇列要終止
bool m_needstop;
};/**************************執行緒池********************************/
//傳遞給同步佇列的最大個數
const int maxtaskcount = 100;
class threadpool
//新增任務
void addtask(const task && task)
private:
//建立numthreads個數的執行緒組
void start(int numthreads)
}//取出任務佇列中的全部,依次執行
void runinthread()
//執行任務
task();}}
}//終止所有任務的執行
void stopthreadgroup()
}m_threadgroup.clear();
}private:
//處理任務的執行緒組
std::list<:shared_ptr>> m_threadgroup;
//同步佇列
syncqueue m_queue;
//執行的標誌,flase代表終止
atomic_bool m_running;
//保證在函式在多執行緒環境中只被呼叫一次
物件池對於建立開銷較大的物件來說很有意義,為了避免重複建立開銷較大的物件,可以通過物件池來優化.
物件池的思路比較簡單,實現建立好一批物件,放到乙個集合中,每當程式需要新的物件時,就從物件池中獲取,程式用完該物件後都會把該物件歸還給物件池.這樣會避免重複建立物件,提高程式效能.
#include
#include
#include
#include
using namespace std;
//要成為不可複製的類,典型的方法是將類的複製建構函式和賦值運算子設定為private或protected
//為了使objectpool為不可複製的類,我們定義了類noncopyable,只需繼承起則可為不可複製的類
class noncopyable
;//物件最大個數
const int maxobjectnum = 10;
template
class objectpool : noncopyable
//init時的模板型別不同所得到的constructname字串不同
//所以相同的初始化型別對應m_object_map中的first相同,不同型別的則不同
auto constructname = typeid(constructor).name();
//cout << "init: " << constructname << endl;
for (size_t i = 0; i < num; i++)
));}
}//從物件池獲取乙個物件
template
std::shared_ptr get()
return nullptr;}};
c 11 實現半同步半非同步執行緒池
隨著深入學習,現代c 給我帶來越來越多的驚喜 c 真的變強大了。事實上非常好理解。分為三層 同步層 通過io復用或者其它多執行緒多程序等不斷的將待處理事件加入到佇列中。這個過程是同步進行的。佇列層 全部待處理事件都會放到這裡。補充下思路 主要是後兩層 佇列層 c 11 通過std function能...
C 11 半同步半非同步執行緒池的實現
include include include include include include include include using namespace std namespace itstation void put const t x void put t x void take list...
C 11 建立乙個執行緒
include class sometask private void work int n char c private std thread taskthread 如 所示,方法start啟動乙個執行緒,執行緒執行本類的另乙個方法work。thread的第乙個建構函式為無參建構函式 thread...