我有基於被寫入到使用boost::asio
僅僅作爲其輸入數據的源,因爲大多數我們的對象的應用程序是網絡通信。由於某些特定的要求,我們現在需要使用共享內存作爲輸入方法。我已經編寫了共享內存組件,它工作得相當好。升壓:: ASIO,共享內存和進程間通信
問題是如何處理從共享內存進程到消費應用程序的數據可供讀取的通知 - 我們需要處理現有輸入線程中的數據(使用boost::asio
),而且我們還需要不阻止輸入線程等待數據。
我已經通過引入到將要從所述共享存儲器提供商處理用信號然後投遞完成處理程序到輸入線程來處理讀取的數據的事件等待的中間螺紋實現這一點。
這也適用於現在,但引入中間線程意味着在大量情況下,我們有額外的上下文切換,然後才能讀取對延遲產生負面影響的數據,以及附加線程也相對昂貴。
這裏是什麼樣的應用程序在做一個簡單的例子:?(不通過interrupt_thread
在不必post
它
#include <iostream>
using namespace std;
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/bind.hpp>
class simple_thread
{
public:
simple_thread(const std::string& name)
: name_(name)
{}
void start()
{
thread_.reset(new boost::thread(
boost::bind(&simple_thread::run, this)));
}
private:
virtual void do_run() = 0;
void run()
{
cout << "Started " << name_ << " thread as: " << thread_->get_id() << "\n";
do_run();
}
protected:
boost::scoped_ptr<boost::thread> thread_;
std::string name_;
};
class input_thread
: public simple_thread
{
public:
input_thread() : simple_thread("Input")
{}
boost::asio::io_service& svc()
{
return svc_;
}
void do_run()
{
boost::system::error_code e;
boost::asio::io_service::work w(svc_);
svc_.run(e);
}
private:
boost::asio::io_service svc_;
};
struct dot
{
void operator()()
{
cout << '.';
}
};
class interrupt_thread
: public simple_thread
{
public:
interrupt_thread(input_thread& input)
: simple_thread("Interrupt")
, input_(input)
{}
void do_run()
{
do
{
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
input_.svc().post(dot());
}
while(true);
}
private:
input_thread& input_;
};
int main()
{
input_thread inp;
interrupt_thread intr(inp);
inp.start();
intr.start();
while(true)
{
Sleep(1000);
}
}
有沒有什麼辦法讓在input_thread
直接處理的數據的假設是,中斷線程完全由來自外部應用程序的定時驅動(通知數據可通過信號量獲得)並且,假設我們完全控制了消費應用程序和提供應用程序,我們還有其他對象需要處理input_thread
對象(所以我們不能簡單地阻塞並等待那裏的信號量對象)。 al將減少通過共享內存提供應用程序進入的數據的開銷,CPU利用率和延遲。
如果你在* NIX,最簡單的方法是使用UNIX管道通知,管這麼一端被添加到'input_thread'作爲一個普通插座。你仍然會產生同步等開銷,但保存一個冗餘副本(到/從套接字緩衝區)。您可以通過套接字發送偏移量和長度,然後直接爲shmem編制索引。 – Useless 2012-12-03 10:19:29
在Windows中,您可以使用windows :: object_handle來異步地直接在同步對象上等待。 – 2012-12-30 20:45:28