我正在使用 async_read_some 从保存在名为 _data 的 char[] 的端口中读取数据。它的缓冲区大小对于每个请求都足够大:
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* 来向请求添加一些附加信息(如时间戳等)。然后将此 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));
}
}
session_class 包含上面提到的函数 start() 和 handle_read(x,y)。LOGGING_CLASS 提供了写入日志文件的类(包含函数 writeCacheToFile() 和 writeToMemory(char*))。log(上面提到的)是此类的一种。
EOE:编辑结束
如果我尝试使用 boost::threads 修复外包缓存部分(将接收到的 char* 附加到 std::string),它最终会完全混淆 memoryBuffer
它真的是 std::strings 的线程安全还是我错过的其他东西?
提前感谢您的帮助!:)
保罗