关于多线程:需要知道如何检查输入的字符串是否已在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"终止字符,然后使用该检查来知道字符串已完成,然后清空缓冲区。但是,当我这样做时,我出错了界限。

感谢您的时间


我不太确定我得到的情况,但听起来你想要一个代理:

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

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

正如托尼正确指出的那样,这使得锁不必要地长。只有"LogSingleton才需要锁定。想象一下:

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有时间处理队列。