Лучший способ обработки буфера чтения в C ++ - PullRequest
1 голос
/ 17 июня 2011

Я работаю на сервере Linux, используя epoll.У меня есть этот код для чтения буфера

 int str_len = read(m_events[i].data.fd, buf, BUF_SIZE);

 if (str_len == 0) {
      if (!removeClient(m_events[i].data.fd))
          break;
      close(m_events[i].data.fd);
 } else {
      char *pdata = buf;
      pushWork(pdata);
 }

buf объявлен так

buf[BUF_SIZE]

функция pushWork объявлена ​​так

 pushWork(char *pdata){
     push pdata to the thread pool's queue 
 }
* 1009У char * pdata = buf есть проблема, так как он просто указывает на буфер, и буфер будет перезаписан всякий раз, когда поступают новые данные. Так что мне нужно memcpy?

Кроме того, есть ли другой хороший способ справиться с этим в C ++?Этот код в стиле c, я думаю, у меня есть лучший способ сделать это на c ++.

Ответы [ 3 ]

2 голосов
/ 17 июня 2011

Есть ли другой хороший способ справиться с этим в C ++?Этот код вроде стиля c, я думаю, у меня есть лучший способ сделать это на c ++

Как я и предлагал в одном из ваших предыдущих вопросов , Boost.Библиотека Asio является де-факто сетевой библиотекой C ++.Я настоятельно рекомендую вам потратить некоторое время на чтение и изучение примеров, если вы пишете сетевое приложение на C ++.

0 голосов
/ 17 июня 2011

Вам нужно будет сделать memcpy (или что-то эквивалентное), если вы не можете сделать это так, чтобы данные в (buf) никогда не были нужны после возврата pushWork ().Если вы можете позволить себе всю обработку данных буфера внутри pushWork (), OTOH, копирование буфера не требуется.

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

Что касается "C ++-способа", яЯ уверен, что они есть, но я не знаю, что они обязательно улучшат вашу программу.Способ C работает нормально, зачем исправлять то, что не сломано?

(Еще одна вещь, на которую следует обратить внимание: если вы используете неблокирующий ввод / вывод, тогда read () будет иногда читать и возвращать меньше, чем BUF_SIZEбайты, в этом случае вам понадобится логика для обработки этой возможности. Если вы используете блокирующий ввод / вывод, OTOH, read () иногда будет блокироваться на длительные периоды (например, если клиентский компьютер умирает, отправив только половину буфера)который заблокирует ваш цикл epoll и сделает его не отвечающим, возможно, на несколько минут. Это более сложная проблема, поэтому я обычно заканчиваю тем, что использую неблокирующий ввод / вывод, даже если получить больший боль становится правильным.

0 голосов
/ 17 июня 2011

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

То, что вы можете сделать, это malloc () буфер, скопировать полезную нагрузку в этот буфер malloc и передать его потоку, и позволить потоку освободить этот буфер, как только это будет сделано. Просто обязательно освободите его, иначе произойдет утечка памяти.

пример кода:

char * p;

p = (char *)malloc(str_len+1);
memcpy(p, buf, str_len+1);

pushWork(p); //free p inside, after use.
...