作爲一名程序員,我想我們應該都寫過producer和consumer的模型,應爲他的用途實在是太廣泛了,比如之前服務器裏使用到的actor隊列,還有一些對於計算量比較大的任務,都是前端快速接受請求,放到隊列,然後後面的線程池取出隊列執行並異步返回,都是使用的producer和consumer方式來實現的,我簡單的畫了一張圖:
在代碼層面的實現無非是用一個隊列,然後再producer和consumer在寫入和讀取時兩端加鎖,使用condition實現等待,以此來協調producer,consumer的工作,如果用一個現實生活中的例子來解釋的話,就像是代理銷售產品,producer就是工廠,中間的隊列就是代理商,我們就是消費者,從運營成本上來講,這種方式加大了消費者的支出,因爲代理商要獲得收益,那可不可以我們直接去工廠預定他們的產品,然後根據每一個用戶們的需求在原來的基礎上再DIY一下,最後給consumer呢,答案是可以的,而且還能保證絕對的公平,不信你可以看下面實現:
使用c++中的function/async/promise/packaged_task說白了就是異步回調函數,和feture來實現這種模型。
下面是僞代碼的實現,看得懂就ok了
生產者,如果你想的話可以做成一個隊列
class producer
{
public:
void operator()()
{
// 一步等待任務
// 任務來了,打包成package,然後使用round robbins算法調用funcs裏面的一個callback就ok了其他的不用管,如callback(package)
}
void register(callback a)
{
funcs.push_back(a);
}
private
queue<callback> funcs; //callback 可以爲上面說到的異步回調函數中的任何一種,我下面用到的是
}
producer farms;
// 用戶1,以及自定義的DIY函數
void task_lambda() {
// Res爲DIYpackage之後返回的類型,這個根據需求定
std::packaged_task<Res (package)> task([](package candy) {return candy; });
std::future<int> result = task.get_future();
while (true)
{ farms.register(task); std::cout << "task_lambda:\t" << result.get() << '\n';
}
}
// 用戶2的DIY
Res f(package a)
{
return process(a);
}
void task_bind() { std::packaged_task<Res(package)> task(std::bind(f, _1)); std::future<int> result = task.get_future(); while (true)
{ std::cout << "task_bind:\t" << result.get() << '\n';
}
}
//用戶3的DIY
Res func(package a)
{
return process1(a);
}
void task_thread() { std::packaged_task<Res(package)> task(func); std::future<int> result = task.get_future(); while (true)
{ std::cout << "task_thread:\t" << result.get() << '\n';
}
}
// 可以開始啓動工作了 int main() { boost::thread th1(boost::bind(task_lambda)); boost::thread th2(task_bind); boost::thread th3(task_thread);
th1.join();
th2.join();
th3.join();
}
甩掉代理商的感覺怎麼樣,簡單而且容易實現,這裏還用到了函數式編程的思想,從c++的標準的演變來看,感覺c++從注重語法到現在注重應用的趨勢越來越明顯,當然這只是爲了我們能夠更簡單,更快捷的開發我們的程序,以上是一些小的體驗和心得,歡迎大家一起溝通交流。