Need to know how to check if the inputted string has terminated within a thread-safe logger in C++
如果我的问题不明确,我对此非常陌生并道歉。
我用C ++创建了一个线程安全记录器。该记录器将用于大型程序和将从多个地方调用。我正在使用单例,因此只有一个记录器实例。该记录器输出到文件&到控制台。它的行为类似于cout;它接收来自另一个文件的字符串,(如果需要连接它),将peices存储在缓冲区中,直到字符串完成,然后使用cout输出。该字符串存储为const char *。现在,互斥锁被锁定在一个函数中并在另一个函数中解锁(这是我的问题所在),它使endl运算符超载。
我的问题是,只有当用户在调用记录器的其他文件中写入endl时,此函数(互斥锁被解锁)才有效。我需要这是一个多功能的实用程序,它不依赖于用户写的内容,因为用户可能不会使用endl或者可能经常使用它。我现在需要一些方法让我的记录器识别字符串(来自另一个文件)何时完成,以便它可以清空缓冲区。目前,endl就像一个关键字&我需要一些方法让它在没有任何关键词的情况下运作。
我最初认为我可以找到一些方法来检查字符串中的" 0"终止字符,然后使用该检查来知道字符串已完成,然后清空缓冲区。但是,当我这样做时,我出错了界限。
感谢您的时间
我不太确定我得到的情况,但听起来你想要一个代理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | class LogSingleton { public: LogSingleton& instance() { /* ... */ } void lock(); // lock mutex void unlock(); // unlock mutex template <typename T> friend LogSingleton& operator<<(LogSingleton& pLog, const T& pX) { // needs to be locked first assert(is_locked()); /* output pX however */ return pLog; } }; class LogProxy { public: LogProxy() { // manage lock in proxy LogSingleton::instance().lock(); } ~LogProxy() { LogSingleton::instance().unlock(); } }; // forward input into the proxy to the log, knowing it's locked template <typename T> LogProxy& operator<<(LogProxy& pProxy, const T& pX) { LogSingleton::instance() << pX; return pProxy; } // now expose proxy typedef LogProxy log; |
而你这样做:
1 | log() <<"its locked now" <<"and the temporary will die" <<"here ->"; |
锁定在构造函数和析构函数中完成,最后调用析构函数。
正如托尼正确指出的那样,这使得锁不必要地长。只有"
1 2 | log() <<"this next function takes 5 minutes" << my_utterly_crappy_function() <<"ouch"; |
Nothings登录但互斥锁已锁定很长时间。更好的是缓冲输出然后立即输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class LogProxy { public: ~LogProxy() { // manage lock in proxy LogSingleton::instance().lock(); // no-throw, or wrap mutex use in a scoped-lock LogSingleton::instance() << mBuffer.rdbuf(); LogSingleton::instance().unlock(); } // buffer output template <typename T> friend LogProxy& operator<<(LogProxy& pProxy, const T& pX) { mBuffer << pX; return pProxy; } private: std::ostringstream mBuffer; }; |
现在,在准备好输出缓冲区之前,不会获取锁定。
校验
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5072104.html
我们的想法是创建线程本地"代理",它将调用实际的线程安全日志记录功能。
通常,在一个函数中使用互斥锁并在另一个函数中解锁是个坏主意。它应该在同一个功能中锁定和解锁。
我创建了类似的东西,通常我创建了一个名为Error的C ++类。
这样用户就会创建一个Error对象,并且该错误对象会处理所有终止内容。然后将错误对象发送到ErrorLogger的队列,并在ErrorLogger队列为空时终止错误记录器。然后您不必担心互斥锁,因为ErrorLogger有时间处理队列。