繁体   English   中英

需要知道如何在C ++中的线程安全记录器中检查输入的字符串是否已终止

[英]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”终止字符,然后使用该检查来知道字符串已完成,然后清空缓冲区。 但是,当我这样做时,我会越界错误。

感谢您的时间

我不太确定会遇到这种情况,但是听起来您想要代理:

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;

您可以这样做:

log() << "its locked now" << "and the temporary will die" << "here ->";

锁定在构造函数和析构函数中完成,并且在最后调用析构函数。


正如Tony正确指出的那样,这会不必要地长时间保持锁。 只有将“最终”输出输出到LogSingleton时才需要锁定。 想象一下:

log() << "this next function takes 5 minutes"
        << my_utterly_crappy_function() << "ouch";

什么都没有记录,但互斥锁已锁定很长时间了。 最好将输出缓冲起来,然后一次全部输出:

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;
};

现在,在准备好输出缓冲区之前,不会获取任何锁。

通常,在一个功能中具有互斥锁并在另一个功能中解锁是一个坏主意。 它应该在相同的功能中被锁定和解锁。

我创建了类似的东西,通常我制作了一个名为Error的C ++类。

这样,用户可以创建一个Error对象,并且该Error对象可以处理所有终止操作。 然后,错误对象被发送到ErrorLogger的队列,并且ErrorLogger队列为空时,错误记录器终止。 然后,您不必担心互斥锁,因为ErrorLogger有时间处理队列之外的内容。

检查https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5072104.html

这个想法是创建线程本地的“代理”,该代理将调用实际的线程安全日志记录功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM