Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> обертка над asio сокетом 
V
    Опции темы
boostcoder
Дата 10.4.2011, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



всем доброго вечера.

хочу написать обертку над asio сокетом, дабы улучшить юзабильность.
хочу избавиться от ручного написания байнда и хранения записываемого буфера до окончания асинхронной операции.
это и хочу обсудить.

сейчас вижу интерфейс таким:
Код

struct socket {
   template<typename T, typename F>
   void async_write(T& buf, F handler) {
      ... = buf.begin();
      ... = buf.end();
   }

   template<typename F>
   void async_write(char* buf, size_t len, F handler) {
   }
};


чтоб использовать так:
Код

socket sock;

void handler(const boost::system::error_code& e) {}

std::string str;
boost::array<char, 32> arr;
std::vector<char> vec;

sock.async_write(str, &handler);
sock.async_write(arr, &handler);
sock.async_write(vec, &handler);


первый вопрос - есть ли смысл вообще в обертке?
второй вопрос - в случае записи указателя на char, есть ли смысл копировать данные в какой-то внутренний буфер обертки? или просто запоминать указатель, по при вызове хэндлера - освобождать память на которую он указывает?
третий вопрос - что вообще нужно такой обертке, и что не нужно?

спасибо.

PM WWW   Вверх
borisbn
Дата 10.4.2011, 23:45 (ссылка) |  (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(boostcoder @  10.4.2011,  20:11 Найти цитируемый пост)
первый вопрос - есть ли смысл вообще в обертке?

думаю есть, т.к. довольно часто приходится делать одно и то же, наступать на те же грабли, копипастить... брррр

Цитата(boostcoder @  10.4.2011,  20:11 Найти цитируемый пост)
второй вопрос - в случае записи указателя на char, есть ли смысл копировать данные в какой-то внутренний буфер обертки? или просто запоминать указатель, по при вызове хэндлера - освобождать память на которую он указывает?

IMHO однозначно копировать. чтобы не получилось такой ситуации
Код

sock.async_write( obj.getTempString().c_str(), ...


Цитата(boostcoder @  10.4.2011,  20:11 Найти цитируемый пост)
третий вопрос - что вообще нужно такой обертке, и что не нужно?

IMHO лучше интерфеса, чем этот не придумаешь

Это сообщение отредактировал(а) borisbn - 10.4.2011, 23:53


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
bsa
Дата 10.4.2011, 23:51 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(boostcoder @  10.4.2011,  20:11 Найти цитируемый пост)
второй вопрос - в случае записи указателя на char, есть ли смысл копировать данные в какой-то внутренний буфер обертки?
да, конечно.
Цитата(boostcoder @  10.4.2011,  20:11 Найти цитируемый пост)
или просто запоминать указатель, по при вызове хэндлера - освобождать память на которую он указывает?
ни в коем случае. Память освобождаться должна там, где была выделена.
PM   Вверх
boostcoder
Дата 11.4.2011, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  10.4.2011,  23:45 Найти цитируемый пост)
однозначно копировать

Цитата(bsa @  10.4.2011,  23:51 Найти цитируемый пост)
да, конечно.

допустим...
тогда встает вопрос о размере внутреннего буфера обертки.
1. должен указываться в конструкторе?
2. или увеличивается столько, сколько свободной памяти на машине?
3. расходы на выделение памяти/копирование не пугают?

у меня есть такое предложение: обязать пользователя передавать в сокет смарт_поинтер инициализированный/заполненный юзером.
в этом есть есть два плюса:
1. не нужно ничего копировать. т.к. внутренний буфер становится очередью из смарт_поинтеров
2. не нужно руками освобождать память.

PM WWW   Вверх
mes
Дата 11.4.2011, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  10.4.2011,  19:11 Найти цитируемый пост)
хочу избавиться от ручного написания байнда и хранения записываемого буфера до окончания асинхронной операции.

нельзя ли пример строчки которая Вас не устраивает, с указанием неугодных  моментов ?.. 


--------------------
PM MAIL WWW   Вверх
borisbn
Дата 11.4.2011, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(boostcoder @  11.4.2011,  11:14 Найти цитируемый пост)
1. должен указываться в конструкторе?

IMHO некрасиво

Цитата(boostcoder @  11.4.2011,  11:14 Найти цитируемый пост)
2. или увеличивается столько, сколько свободной памяти на машине?

внутренний буфер будет увеличиваться только в том случае, если юзер будет подавать данные быстрее, чем они будут уходить получателю... Если юзер так рассчитал систему - то он сам виноват. Библиотека (обёртка) тут не при чём.

Цитата(boostcoder @  11.4.2011,  11:14 Найти цитируемый пост)
3. расходы на выделение памяти/копирование не пугают?

Думаю, что сама отправка (скорость передачи по каналу) будет на порядки дольше, чем обращение к менеджеру памяти и копирование из одной области памяти в другую. Даже если передача данных будет происходить по 127.0.0.1


Цитата(boostcoder @  11.4.2011,  11:14 Найти цитируемый пост)
обязать пользователя передавать в сокет смарт_поинтер инициализированный/заполненный юзером.

В этом случае юзерская ф-ция отправки, например, строки будет выглядеть некрасиво
Код

void user_send( const std::string & str ) {
    size_t sz = str.length();
    shared_ptr< char > p( new char[ sz + 1 ] );
    strcpy( p, str.c_str() );
    sock.async_write( p );
}

вместо
Код

void user_send( const std::string & str ) {
    sock.async_write( str.c_str(), str.length() );
}




--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 11.4.2011, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  11.4.2011,  12:44 Найти цитируемый пост)
Думаю, что сама отправка (скорость передачи по каналу) будет на порядки дольше, чем обращение к менеджеру памяти и копирование из одной области памяти в другую.

тут Вы ошибаетесь.
в этой теме, возьмите последние исходники и посмотрите. там очень простой код. выделение 13 байт, sprintf(), передача в async_write(), в хэндлере delete[]. ничего сложного ведь ;) но на 100мбитной сети, происходит 220000-250000 таких последовательностей, что полносьтю загружает одно ядро. вроде бы казалось, ничего сложного в этих операциях нет. но профайлер говорит что 48 процентов времени уходит только на new!

в общем, выделение памяти и инициализацию смарт_поинтера оставил на юзера. помоему, очень даже юзабельно получилось smile 
пожелания/рекомендации/критика приветствуются.

класс сокета:
Код


#ifndef _simple_socket_hpp_included_
#define _simple_socket_hpp_included_

#include <queue>
#include <stdexcept>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/function.hpp>
#include <boost/shared_array.hpp>
#include <boost/system/error_code.hpp>

/***************************************************************************/

struct simple_socket: private boost::noncopyable {
   typedef void(*read_handler_type)(const boost::system::error_code&, boost::shared_array<char>, size_t);
   typedef void(*write_handler_type)(const boost::system::error_code&, boost::shared_array<char>, size_t);

   simple_socket(boost::asio::io_service& ios)
      :sock(ios),
      write_in_process(false),
      read_in_process(false)
   {}

   ~simple_socket() {
      clear_read_queue();
      clear_write_queue();
      disconnect();
   }

   boost::asio::ip::tcp::socket& socket() { return sock; }

   void connect(const std::string& ip, boost::uint16_t port) {
      sock.connect(
         boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(ip), port)
      );
   }
   void disconnect() {
      if ( sock.is_open() ) {
         sock.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
         sock.close();
      }
   }

   size_t read_queue_size() const { return read_queue.size(); }
   size_t write_queue_size() const { return write_queue.size(); }

   void clear_read_queue() {
      read_queue.clear();
      if ( sock.is_open() ) sock.cancel();
   }
   void clear_write_queue() {
      write_queue.clear();
      if ( sock.is_open() ) sock.cancel();
   }

   template<typename F>
   void async_write(boost::shared_array<char> arr, size_t size, F f) {
      if ( !sock.is_open() ) throw std::runtime_error("socket is not connected");
      if ( !arr.get() || !size ) return;
      write_queue.push({f, arr, size});
      if ( !write_in_process ) {
         write_in_process = true;
         write_exec();
      }
   }
   void async_write(boost::shared_array<char> arr, size_t size, write_handler_type f) {
      async_write(arr, size, boost::bind(f, _1, _2, _3));
   }
   template<typename Obj>
   void async_write(boost::shared_array<char> arr,
                    size_t size,
                    Obj* obj,
                    void(Obj::*handler)(const boost::system::error_code&, boost::shared_array<char>, size_t))
   {
      async_write(arr, size, boost::bind(handler, obj, _1, _2, _3));
   }
   
   template<typename F>
   void async_read(size_t size, F f) {
      if ( !sock.is_open() ) throw std::runtime_error("socket is not connected");
      if ( !size ) return;
      read_queue.push({f, boost::shared_array<char>(), size});
      if ( !read_in_process ) {
         read_in_process = true;
         read_exec();
      }
   }
   void async_read(size_t size, read_handler_type f) {
      async_read(size, boost::bind(f, _1, _2, _3));
   }
   template<typename Obj>
   void async_read(size_t size,
                   Obj* obj,
                   void(Obj::*handler)(const boost::system::error_code&, boost::shared_array<char>, size_t))
   {
      async_read(size, boost::bind(handler, obj, _1, _2, _3));
   }

private:
   typedef boost::function<void(const boost::system::error_code&, boost::shared_array<char>, size_t)> handler_type;
   
   struct pair {
      handler_type handler;
      boost::shared_array<char> buf;
      size_t size;
   };

   void write_exec() {
      pair p = write_queue.pop();

      boost::asio::async_write(
         sock,
         boost::asio::buffer(p.buf.get(), p.size),
         boost::bind(
            &simple_socket::write_exec_handler,
            this,
            p,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred
         )
      );
   }

   void write_exec_handler(pair p, const boost::system::error_code& e, size_t wr) {
      p.handler(e, p.buf, wr);
      if ( !write_queue.empty() ) {
         write_exec();
      } else {
         write_in_process = false;
      }
   }

   void read_exec() {
      pair p = read_queue.pop();
      p.buf.reset(new char[p.size]);

      boost::asio::async_read(
         sock,
         boost::asio::buffer(p.buf.get(), p.size),
         boost::bind(
            &simple_socket::read_exec_handler,
            this,
            p,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred
         )
      );
   }

   void read_exec_handler(pair p, const boost::system::error_code& e, size_t rd) {
      p.handler(e, p.buf, rd);
      if ( !read_queue.empty() ) {
         read_exec();
      } else {
         read_in_process = false;
      }
   }

private:
   template<typename T>
   struct queue {
      void push(T p) {
         boost::mutex::scoped_lock locker(mutex);
         queue.push(p);
      }
      
      T pop() {
         boost::mutex::scoped_lock locker(mutex);
         if ( queue.empty() ) {
            throw std::runtime_error("queue is empty");
         }
         T p = queue.front();
         queue.pop();
         return p;
      }

      void clear() {
         boost::mutex::scoped_lock locker(mutex);
         while ( !queue.empty() ) {
            queue.pop();
         }
      }
      
      bool empty() const {
         boost::mutex::scoped_lock locker(mutex);
         return queue.empty();
      }

      size_t size() const {
         boost::mutex::scoped_lock locker(mutex);
         return queue.size();
      }
      
   private:
      mutable boost::mutex mutex;
      std::queue<T> queue;
   };

   boost::asio::ip::tcp::socket sock;
   
   queue<pair> write_queue;
   bool write_in_process;
   
   queue<pair> read_queue;
   bool read_in_process;
};

/***************************************************************************/

#endif // _simple_socket_hpp_included_



пример 1:
Код


#include "simple_socket.hpp"
#include <iostream>

/***************************************************************************/

void write_handler(const boost::system::error_code& e, boost::shared_array<char> arr, size_t wr) {
   fprintf(stdout, "write_handler(): %s, %d, e = %s\n", arr.get(), wr, e.message().c_str());
   fflush(stdout);
}

void read_handler(const boost::system::error_code& e, boost::shared_array<char> arr, size_t rd) {
   fprintf(stdout, "read_handler(): %s, %d, e = %s\n", arr.get(), rd, e.message().c_str());
   fflush(stdout);
}

/***************************************************************************/

int main() {
   enum {
      array_size = 32,
      count = 1024
   };

   boost::asio::io_service ios;
   simple_socket socket(ios);

   try {
      socket.connect("127.0.0.1", 44550);

      for(int idx = 0; idx < count; ++idx) {
         boost::shared_array<char> arr(new char[array_size]);
         sprintf(arr.get(), "item: %d", idx);

         socket.async_write(arr, array_size, &write_handler);
      }
      
      for(int idx = 0; idx < count; ++idx) {
         socket.async_read(array_size, &read_handler);
      }

      ios.run();
      socket.disconnect();
   }
   catch(const std::exception& e) {
      std::cout << "[exception] " << e.what() << std::endl;
   }
}

/***************************************************************************/



пример 2:
Код


#include "simple_socket.hpp"
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

/***************************************************************************/

struct client_impl {
   client_impl(boost::asio::io_service& ios, const std::string& ip, boost::uint16_t port)
      :socket(ios),
      str("string data")
   {
      socket.connect(ip, port);
   }

   void write() {
      const size_t len = strlen(str);
      boost::shared_array<char> arr(new char[len]);
      strcpy(arr.get(), str);
      
      socket.async_write(arr, len, this, &client_impl::write_handler);
   }
   void read() {
      socket.async_read(strlen(str), this, &client_impl::read_handler);
   }

   void write_handler(const boost::system::error_code& e, boost::shared_array<char> arr, size_t wr) {
      fprintf(stdout, "write_handler(): %s, %d, e = %s\n", arr.get(), wr, e.message().c_str());
      fflush(stdout);
   }

   void read_handler(const boost::system::error_code& e, boost::shared_array<char> arr, size_t rd) {
      fprintf(stdout, "read_handler(): %s, %d, e = %s\n", arr.get(), rd, e.message().c_str());
      fflush(stdout);
   }

private:
   simple_socket socket;
   const char* str;
};

/***************************************************************************/

int main() {
   boost::asio::io_service ios;
   client_impl client(ios, "127.0.0.1", 44550);

   try {
      client.write();
      client.read();
      ios.run();
   }
   catch(const std::exception& e) {
      std::cout << "[exception] " << e.what() << std::endl;
   }
}

/***************************************************************************/



пример 3:
Код


#include "simple_socket.hpp"
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

/***************************************************************************/

struct client_impl {
   void write_handler(const boost::system::error_code& e, boost::shared_array<char> arr, size_t wr) {
      fprintf(stdout, "write_handler(): %s, %d, e = %s\n", arr.get(), wr, e.message().c_str());
      fflush(stdout);
   }

   void read_handler(const boost::system::error_code& e, boost::shared_array<char> arr, size_t rd) {
      fprintf(stdout, "read_handler(): %s, %d, e = %s\n", arr.get(), rd, e.message().c_str());
      fflush(stdout);
   }
};

/***************************************************************************/

int main() {
   boost::asio::io_service ios;
   simple_socket socket(ios);

   client_impl client;

   try {
      socket.connect("127.0.0.1", 44550);

      const size_t arr_size = 32;
      boost::shared_array<char> arr(new char[arr_size]);
      sprintf(arr.get(), "data string");
      
      socket.async_write(arr, arr_size, &client, &client_impl::write_handler);

      socket.async_read(arr_size, &client, &client_impl::read_handler);
      
      ios.run();
   }
   catch(const std::exception& e) {
      std::cout << "[exception] " << e.what() << std::endl;
   }
}

/***************************************************************************/



всем спасибо smile

Добавлено через 6 минут и 9 секунд
Цитата(mes @  11.4.2011,  12:00 Найти цитируемый пост)
нельзя ли пример строчки которая Вас не устраивает, с указанием неугодных  моментов ?

не нравится постоянно писать байнд.
в добавок, если сигнатура не соответствует, или не соответствует кол-во плейсхолдеров, или их вовсе нет - то глядеть в 120 строк вывода об ошибке сомнительное удовольствие.

Это сообщение отредактировал(а) boostcoder - 11.4.2011, 16:35

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  simplesocket.zip 3,33 Kb
PM WWW   Вверх
boostcoder
Дата 11.4.2011, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



эм... такой вопрос: а есть ли смысл добавлять методы для синхронных операций?
IMHO - лишнее.
PM WWW   Вверх
borisbn
Дата 11.4.2011, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(boostcoder @  11.4.2011,  16:32 Найти цитируемый пост)
профайлер говорит что 48 процентов времени уходит только на new!

профайлер не знает, сколько времени уходит непосредственно на отправку/приём, т.к. они асинхронные
В Вашем примере ровно столько же new делается на стороне клиента юзера

Цитата(boostcoder @  11.4.2011,  16:32 Найти цитируемый пост)

for(int idx = 0; idx < count; ++idx) {
         boost::shared_array<char> arr(new char[array_size]);

думаю, что эти new как-то можно соптимизировать. и лучше это сделать в одном месте - в обёртке, а не каждый раз у юзера. А не замахнуться ли нам на Вильяма нашего Собственного Менеджера Памяти smile

Цитата(boostcoder @  11.4.2011,  16:53 Найти цитируемый пост)
а есть ли смысл добавлять методы для синхронных операций?

думаю, Вы правы. Лишнее. А вот добавить [необязательные] handler'ы connected и disconnected можно smile


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 11.4.2011, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  11.4.2011,  17:15 Найти цитируемый пост)
 Вашем примере ровно столько же new делается на стороне клиента юзера

это да. но я хотел сказать то, что ко всем new не нужно еще и добавлять расходы на копирование.

Цитата(borisbn @  11.4.2011,  17:15 Найти цитируемый пост)
думаю, что эти new как-то можно соптимизировать. и лучше это сделать в одном месте - в обёртке, а не каждый раз у юзера.

как, например?
пул памяти?

Цитата(borisbn @  11.4.2011,  17:15 Найти цитируемый пост)
connected и disconnected

ага. а потом кто-то скажет еще добавить аксессоры для ip:port, и что-то еще smile 
у обертки есть метод socket() который возвращает ссылку на внутренний сокет. а у него есть все необходимые методы.

эта обертка - всего лишь сокет.
над ней можно написать другую обертку, к примеру обертку сериализатора/десериализатора для абстрагирования от типа. т.к. сейчас обертка работает только с массивом чаров.


Это сообщение отредактировал(а) boostcoder - 11.4.2011, 18:24
PM WWW   Вверх
boostcoder
Дата 11.4.2011, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  11.4.2011,  17:15 Найти цитируемый пост)
А не замахнуться ли нам на Вильяма нашего Собственного Менеджера Памяти

предлагаешь написать менеджер памяти?
и кто такой "Вильяма" ?

PM WWW   Вверх
mes
Дата 11.4.2011, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  11.4.2011,  16:39 Найти цитируемый пост)
и кто такой "Вильяма" 

http://www.bibliotekar.ru/encSlov/a/25.htm


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 11.4.2011, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, спасибо.
я никогда не понимал классику. потому не смотрел. потому не знаю таких высказываний.

хотя... Кин-дза-дза мне нравится. помоему это единственное из классики что я могу посмотреть без принуждения..


Это сообщение отредактировал(а) boostcoder - 11.4.2011, 18:44
PM WWW   Вверх
boostcoder
Дата 11.4.2011, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



mes, кстати. как Вам такой сокет? ;)
PM WWW   Вверх
phprus
Дата 11.4.2011, 20:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 22.8.2006

Репутация: 1
Всего: 3



Цитата(borisbn @  11.4.2011,  15:44 Найти цитируемый пост)
Думаю, что сама отправка (скорость передачи по каналу) будет на порядки дольше, чем обращение к менеджеру памяти и копирование из одной области памяти в другую. Даже если передача данных будет происходить по 127.0.0.1

Аллокации, влияют не так сильно, а вот копирование памяти, ее предварительное зануление(если используется std::vector) начинает тормозить уже на скорости обмена с сетью порядка 200Мбит/с (выведено из опыта излишней буферизации в своем приложении), то есть скорость работы приложения ограничивается скоростью копирования памяти.

Цитата(borisbn @  11.4.2011,  15:44 Найти цитируемый пост)
    shared_ptr< char > p( new char[ sz + 1 ] );

shared_ptr не может принимать массивы, и не во всех случаях безопасен при многопоточности. В первом случае есть shared_array, а второй так просто не решается :(
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.2384 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.