Я использую async_read_some для чтения данных из порта, который сохранен в char [] с именем _data.Его размер буфера достаточно велик для каждого запроса:
void start() {
socket_.async_read_some(boost::asio::buffer(data_,BUFFERSIZE),make_custom_alloc_handler(allocator_,boost::bind(&attentionSession::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
}
void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
string ip = socket_.remote_endpoint().address().to_string();
log->processData(data_,ip,"memory");
strcpy(data_,"");
}
processData добавляет некоторую дополнительную информацию (например, метку времени и т. Д.) К запросу, копируя его в другой недавно выделенный символ *.Затем этот char [] отправляется в writeToMemory (char *), чтобы добавить этот char * к std :: string memoryBuffer:
void writeCacheToFile() {
// This function writes buffer data to the log file
char* temp = new char[memoryBuffer.length() + 1];
strcpy(temp, memoryBuffer.c_str());
writeToFile(temp);
delete[] temp;
memoryBuffer.clear();
}
void writeToMemory(char* data) {
int maxSize = 1024;
// Checks if char* data would 'fit' into the pre-defined maxSize
if ((strlen((const char*)data) + memoryBuffer.length()) >= maxSize) {
writeCacheToFile(); // If not the cache memoryBuffer is saved first
}
memoryBuffer.append((const char*) data);
cout << memoryBuffer.length() << endl;
}
. Это работает, но если есть постоянные запросы (бомбардировка его запросами)запутаться.Как вы можете видеть выше в функции writeToMemory (), я добавил строку, чтобы вывести текущую длину memoryBuffer, и именно здесь я думаю, что она имеет отношение к безопасности потока std :: strings:
96
188
284
3639
94
190
286
2591
102
198
294
388
484
2591
96
2591
96
190
286
2591
Длина каждого (обработанного процессом processData ()) запроса составляет 96 символов.Но здесь длина memoryBuffer просто увеличивается и уменьшается - некоторые длины даже больше, чем maxSize (1024 символа).
РЕДАКТИРОВАТЬ: Сэм указал, что я должен добавить еще немного кода.Вот как я запускаю io_service:
boost::asio::io_service ioService;
boost::scoped_ptr<boost::thread> ioServiceThread;
server_class server (ioService,PORT); // Create server instance
ioServiceThread.reset (new boost::thread ( boost::bind ( &boost::asio::io_service::run, &ioService ) ) );
// Only one threaded io_service (to receive user inputs in main() function)
И это функция async_acceptor после выполнения запроса:
typedef boost::shared_ptr<session_class> session_ptr;
void handleAccept(session_ptr thisSession, const boost::system::error_code& error) {
if (!error) {
thisSession->start(); // Calls the start() function above
thisSession.reset(new session(ioService,LOGGING_CLASS));
acceptor.async_accept(thisSession->socket(),boost::bind(&server_class::handleAccept, this, thisSession, PLACEHOLDER_ERROR));
}
}
Сеансовый класс содержит функции start () и handle_read (x,у) упоминалось выше.LOGGING_CLASS предоставляет класс для записи файлов журнала (содержит функции writeCacheToFile () и writeToMemory (char *)).log (упомянутый выше) является разновидностью этого класса.
EOE: END OF EDIT
Если я пытаюсь исправить аутсорсинг кэширующей части (добавление полученного символа * кstd :: string) с boost :: threads заканчивается полностью перепутанным memoryBuffer
Действительно ли это потокобезопасность std :: strings или чего-то еще, что я пропустил?
Спасибо заВаша помощь заранее!:)
Пол