隨著深入學習,現代c++給我帶來越來越多的驚喜…c++真的變強大了。
事實上非常好理解。分為三層補充下思路:同步層:通過io復用或者其它多執行緒多程序等不斷的將待處理事件加入到佇列中。這個過程是同步進行的。
佇列層:全部待處理事件都會放到這裡。
主要是後兩層
佇列層:c++11 通過std::function能夠將函式封裝為物件。那麼我們乙個函式也就是乙個任務。通過vector或list等容器來儲存這些」任務」來供後面訪問。由於會出現競爭資源的問題,所以我們要加鎖,而且通過條件變數的條件來喚醒其它堵塞在鎖上的執行緒。當然你想避免執行緒堵塞浪費資源能夠用帶時間的鎖std::time_mutex。看張圖:非同步層:c++11 將執行緒也封裝為了物件,那麼我們建立乙個容器儲存執行緒物件,讓他們去佇列層取任務並執行,執行完並不結束該執行緒而是歸還給容器(執行緒池)。
c++11 智慧型指標
c++11 物件移動
c++11 lambda,bind,function
**:
同步佇列:
#include
#include
#include
#include
#include
template
class synqueue
//加入事件,左值拷貝和右值移動
void put(const t&x)
void put(t &&x)
//從佇列中取事件,取全部事件
void take(std::list
&list)
);if(m_needstop)
return;
list = std::move(m_queue);
//喚醒其它堵塞在相互排斥鎖的執行緒
m_notfull.notify_one();
}//取乙個事件
void take(t &t)
);if(m_needstop)
return;
t = m_queue.front();
m_queue.pop_front();
m_notfull.notify_one();
t();
}//停止全部執行緒在同步佇列中的讀取
void stop()
m_notfull.notify_all();
m_notempty.notify_all();
}//隊列為空
bool empty()
//隊列為滿
bool full()
//佇列大小
size_t size()
private:
//往佇列裡加入事件,事件是范型的。c++11我們能夠把函式通過std::function封裝為物件。
template
void add(f &&x)
);if(m_needstop)
return;
m_queue.push_back(std::forward(x));
m_notempty.notify_one();
}//佇列未滿
bool notfull() const
//佇列不為空
bool notempty() const
return !empty;
}private:
std::mutex m_mutex; //相互排斥鎖
std::list
m_queue; //佇列,存放任務
std::condition_variable m_notempty; //佇列不為空的條件變數
std::condition_variable m_notfull; //佇列不為滿的條件變數
int m_maxsize; //任務佇列最大長度
bool m_needstop; //終止標識
};
執行緒池:
#include
#include
#include
#include
#include "synqueue.h"
#include
#include
#include
#include
const
int maxtaskcount = 100;
class threadpool
//銷毀執行緒池
~threadpool(void)
//終止全部執行緒,call_once保證函式僅僅呼叫一次
void stop());}
//加入任務。普通版本號和右值引用版本號
void addtask(const task& task)
void addtask(task && task)
private:
//停止執行緒池
void stopthreadgroup()
m_threadgroup.clear();
}void start(int numthreads)
}//一次取出佇列中全部事件
void runinthread_list()}}
//一次僅僅取乙個事件
void runinthread()
}private:
//執行緒池
std::list
<:shared_ptr>
<:thread>> m_threadgroup;
//任務佇列
synqueuem_queue;
//原子布林值
std::atomic_bool m_running;
//輔助變數->call_once
std::once_flag m_flag;
};int main(int argc, char *ar**)
); }
});std::this_thread::sleep_for(std::chrono::seconds(2));
pool.stop();
thd1.join();
return exit_success;
}
參考書籍:
深入應用c++11完
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實現乙個半同步半非同步執行緒池
在處理大量併發任務的時候,如果按照傳統的方式,乙個請求乙個執行緒來處理請求任務,大量的執行緒建立和銷毀將消耗過多的系統資源,還增加了執行緒上下文切換的開銷,而通過執行緒池技術就可以很好的解決這些問題,執行緒池技術通過在系統中預先建立一定數量的執行緒,當任務請求到來時從執行緒池中分配乙個預先建立的執行...
半同步半非同步 多程序 多執行緒 區別
在 linux高效能伺服器程式設計 中,看到的最厲害的方法基本上就是這個半同步半非同步的方法了。簡直炸天。用到了多程序 多執行緒 epoll i o復用。好像真的很高效能哦。那麼其中多程序和多執行緒的的區別是啥?為了避免在父 子程序之間傳遞檔案描述符,我們將接受新連線的操作放到子程序中。前文的討論,...