65,186
社区成员




#pragma once
#include <boost/thread/condition.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/filesystem.hpp>
#include <queue>
#include <fstream>
namespace MutithreadLog
{
template <typename V>
class SafeQueue
{
public:
typedef typename boost::recursive_mutex::scoped_lock scoped_lock;
SafeQueue(int nCount)
: _limit(nCount)
{
}
void add(V v)
{
scoped_lock lk(_mutex);
while (_limit <= _queue.size())
{
_cond.wait(lk);
}
_queue.push(v);
_cond.notify_one();
}
V pop()
{
scoped_lock lk(_mutex);
while (_queue.size() == 0)
{
_cond.wait(lk);
}
V vRet = _queue.front();
_queue.pop();
_cond.notify_one();
return vRet;
}
int size()
{
scoped_lock lk(_mutex);
return static_cast<int>(_queue.size());
}
bool is_full()
{
scoped_lock lk(_mutex);
if (_limit <= _queue.size())
{
return true;
}
return false;
}
void clearall()
{
scoped_lock lk(_mutex);
while (_queue.size() > 0)
{
_queue.pop();
}
_cond.notify_one();
}
private:
boost::recursive_mutex _mutex;
boost::condition _cond;
std::queue<V> _queue;
unsigned int _limit;
};
enum eLogLevel
{
eNormal = 0,
eWarning,
eError,
eFatal
};
class CLogInfo
{
public:
CLogInfo(const std::string& strLog, const eLogLevel level)
: m_strLog(strLog), m_level(level) {}
~CLogInfo() {}
const std::string& GetLog() const { return m_strLog; }
const eLogLevel GetLogLevel() const { return m_level; }
private:
std::string m_strLog;
eLogLevel m_level;
};
typedef boost::shared_ptr<CLogInfo> CLogInfoPtr;
class CLogger
{
public:
static bool Initialize(const std::string& strPath = "D:\\MyLog\\");
static void UnInitialize();
static bool WriteLog(const std::string& strLog, const eLogLevel level = eNormal);
static void Run();
private:
static SafeQueue<CLogInfoPtr> m_logQueue;
static boost::thread_group m_threadGroup;
static std::ofstream m_ofstream;
};
};
#include "Logger.h"
#include <Windows.h>
#include <sstream>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace MutithreadLog;
using namespace std;
SafeQueue<CLogInfoPtr> CLogger::m_logQueue = SafeQueue<CLogInfoPtr>(1000);
boost::thread_group CLogger::m_threadGroup;
std::ofstream CLogger::m_ofstream;
bool CLogger::Initialize(const std::string& strPath)
{
if (!boost::filesystem::exists(strPath))
boost::filesystem::create_directory(strPath);
string strFileName = strPath + "ImportMonitorLog.txt";
m_ofstream.open(strFileName.c_str(), ios::app);
if (m_ofstream.is_open())
{
m_threadGroup.create_thread(boost::bind(&CLogger::Run));
return true;
}
return false;
}
void CLogger::UnInitialize()
{
m_logQueue.add(CLogInfoPtr());
}
bool CLogger::WriteLog(const std::string& strLog, const eLogLevel level)
{
if (m_ofstream.is_open())
{
m_logQueue.add(CLogInfoPtr(new CLogInfo(strLog, level)));
return true;
}
return false;
}
void CLogger::Run()
{
while(true)
{
CLogInfoPtr logPtr = m_logQueue.pop();
if (logPtr)
m_ofstream << "level:" << logPtr->GetLogLevel() << " " << logPtr->GetLog() << endl;
else
{
m_ofstream.close();
break;
}
}
}
// test code...
void test()
{
int nThreadID = ::GetCurrentThreadId();
while (true)
{
stringstream sstream;
string strTime = boost::posix_time::to_iso_string(boost::posix_time::second_clock::local_time());
int pos = strTime.find('T');
strTime.replace(pos,1,std::string("-"));
strTime.replace(pos + 3,0,std::string(":"));
strTime.replace(pos + 6,0,std::string(":"));
sstream << strTime << " " << nThreadID;
if (!CLogger::WriteLog(sstream.str() , eNormal))
break;
//::Sleep(100);
}
}
int main(void)
{
CLogger::Initialize();
boost::thread_group threads;
for (int i = 0; i < 30; i++)
threads.create_thread(boost::bind(&test));
::Sleep(1000);
CLogger::UnInitialize();
threads.join_all();
getchar();
}
#include <mutex>
#include <vector>
#include <future>
#include <iostream>
template <typename T>
class monitor
{
public:
monitor(T t_ = T()) : t(t_){}
template <typename F>
auto operator()(F f) const->decltype(f(t))
{
std::lock_guard<std::mutex> lock(m);
return f(t);
}
private:
mutable T t;
mutable std::mutex m;
};
int main()
{
std::vector<std::future<void> > fut;
monitor<std::ostream&> mos{ std::cout };
for (int i = 0; i < 5; ++i)
{
fut.push_back(std::async([&, i]{
mos([=](std::ostream& cout){
cout << i << " " << i << '\n';
});
mos([=](std::ostream& cout){
cout << "Hi from " << i << std::endl;
});
}));
}
for (auto& f : fut) f.wait();
mos([](std::ostream& st){
st << "Done\n";
}
);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#include <io.h>
#else
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#define CRITICAL_SECTION pthread_mutex_t
#define _vsnprintf vsnprintf
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
#else
void Lock(CRITICAL_SECTION *l) {
pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
pthread_mutex_unlock(l);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb;
if (NULL==pszFmt||0==pszFmt[0]) return;
_vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
} else {
fclose(flog);
}
}
}
void Log(const char *pszFmt,...) {
va_list argp;
Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
int main(int argc,char * argv[]) {
int i;
#ifdef WIN32
InitializeCriticalSection(&cs_log);
#else
pthread_mutex_init(&cs_log,NULL);
#endif
for (i=0;i<10000;i++) {
Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);
}
#ifdef WIN32
DeleteCriticalSection(&cs_log);
#else
pthread_mutex_destroy(&cs_log);
#endif
return 0;
}
//1-78行添加到你带main的.c或.cpp的那个文件的最前面
//81-85行添加到你的main函数开头
//89-93行添加到你的main函数结束前
//在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中