ofstream.flush没有立即输出到文件
在对客户端程序进行分析时,需要对每步操作服务器响应的日志进行分析。
默认情况下,os会缓存而不是立即输出文件.需要强制flush到文件.
本以为flush可以满足:
log_ostream_->flush();
测试发现并没有立即输出.根据搜索到的资料,尝试了以下各种方法都没有达到预期效果。
// (*log_ostream_)<<std::flush;
//log_ostream_->rdbuf()->pubsetbuf(0,0);
// log_ostream_->flush();
// log_ostream_->rdbuf()->sync();
最后在这里找到了官方的解释:
分析ofstream,basic_filebuf的代码,
virtual int __CLR_OR_THIS_CALL sync()
{ // synchronize C stream with external file
return (_Myfile == 0
|| _Traits::eq_int_type(_Traits::eof(), overflow())
|| 0 <= fflush(_Myfile) ? 0 : -1);
}
_Myt *close()
{ // close the C stream
_Myt *_Ans = this;
if (_Myfile == 0)
_Ans = 0;
else
{ // put any homing sequence and close file
if (!_Endwrite())
_Ans = 0;
if (fclose(_Myfile) != 0)
_Ans = 0;
}
_Init(0, _Closefl);
return (_Ans);
}
Getting a FILE* from a std::fstream
http://stackoverflow.com/questions/109449/getting-a-file-from-a-stdfstream
basic_filebuf没有提供_Myfile的访问方法.
https://msdn.microsoft.com/en-us/library/9yky46tz(v=vs.100).aspx
Buffers are normally maintained by the operating system, which determines the optimal time to write the data automatically to disk: when a buffer is full, when a stream is closed, or when a program terminates normally without closing the stream. The commit-to-disk feature of the run-time library lets you ensure that critical data is written directly to disk rather than to the operating-system buffers. Without rewriting an existing program, you can enable this feature by linking the program's object files with COMMODE.OBJ. In the resulting executable file, calls to _flushall write the contents of all buffers to disk. Only _flushall and fflush are affected by COMMODE.OBJ.
程序连接选项Linker|Input|Additional Dependencies增加:COMMODE.OBJ
问题得以解决.
事件队列阻塞问题
事件队列是一个单线程任务,如果事件处理耗时长(如数据库操作,文件操作)可能导致队列阻塞,进而影响到请求的处理.
事件机制常用于一个请求的后续动作,这些动作的实时性要求不高.
事件机制较定时处理更经济和有效.
修改的策略:
.把耗时的操作由另外的线程执行,事件处理者的任务就是唤醒它.从而避免主要
路径上的阻塞.
class CPOSUPlugin :
public CQQBasePlugin ,
public IEventHandler {
///< 增加
IDeamonTask *data_sync_task_; ///< 数据同步任务
int CPOSUPlugin::Activate() {
parent::Activate();
..
///< 增加
data_sync_task_ = deamon_mgr_->add(deamon_thr_proc_Syncdata,"CPOSUPlugin::OnSyncdataTimerer",this);
return 0;
}
int CPOSUPlugin::OnDataSyncChangedOrderDoc() {
SyncTimeoutdata();
return 0;
}
修改为:
int CPOSUPlugin::OnDataSyncChangedOrderDoc() {
data_sync_task_->SyncTimeoutdata();
return 0;
}