20 Şubat 2018 Salı

process async_pipe Sınıfı

Giriş
Tüm bu yazılanları sarmalayan harika bir sınıf burada. Bu sınıf asenkron olarak çalışır. Eğer senkron olarak çalışmak istersek ipstream sınıfı kullanılabilir.

Constructor
Şöyle yaparız.
boost::asio::io_service ios;

bp::async_pipe in{svc}, out{svc};
Kullanım
Şöyle yaparız.
std::string const CompressCmd = "...";

bp::async_pipe in{svc}, out{svc};
bp::child process(CompressCmd, bp::std_in < in, bp::std_out > out, svc);

async_read_some metodu
Şöyle yaparız.
namespace bp = boost::process;
using boost::asio::mutable_buffer;

void read_loop(bp::async_pipe& p, mutable_buffer buf) {
  p.async_read_some(buf, [&p,buf](std::error_code ec, size_t n) {
    std::cout << "Received " << n << " bytes (" << ec.message() << "): '";
    std::cout.write(boost::asio::buffer_cast<char const*>(buf), n) << "'" << std::endl;
    if (!ec) read_loop(p, buf);
  });
}

int main() {
  boost::asio::io_service svc;

  std::vector<std::string> args { 
     "-c", 
    R"--(for a in one two three four; do
      sleep"$(($RANDOM%2)).$(($RANDOM%10))";
      echo "line $a";
     done)--" };

  bp::async_pipe output(svc);
  bp::child p("/bin/bash", args, bp::std_out > output, svc);

  char buf[1024];
  read_loop(output, bp::buffer(buf));

  svc.run();
}

Diğer
boost::asio::async_read() ve boost::asio::async_write() ile kullanım örnekler.

Okumak
async_pipe ve async_read Kullanımı yazısına taşıdım.

Yazmak
Elimizde gönderilecek veri olsun.
string data = ...;
Şöyle yaparız
boost::asio::async_write(in, boost::asio::buffer(data),
 [&](error_code ec, size_t transferred) {
  ...
  in.close(ec);
  
}); // async
...
svc.run(); // Await all async operations
Örnek
Şöyle yaparız.
std::size_t total_written = 0;
Buffer send_buffer;
boost::asio::high_resolution_timer send_delay(svc);
write_loop = [&write_loop, &in, &ifs, &send_buffer, &total_written, &send_delay] {
  if (!ifs.good())
  {
    error_code ec;
    in.close(ec);
    
    return;
  }
  ifs.read(send_buffer.data(), send_buffer.size());

  boost::asio::async_write(in, boost::asio::buffer(send_buffer.data(), ifs.gcount()),
    [&](error_code ec, size_t transferred) {
    
    total_written += transferred; 
    if (!ec) {
      send_delay.expires_from_now(1s);
      send_delay.async_wait([&write_loop](error_code ec) {
        if (!ec) write_loop(); // continue writing
      });
    }
  });
};
Döngüyü bir kere başlatmak için şöyle yaparız.
write_loop(); // async

Hiç yorum yok:

Yorum Gönder