Log4cplus api在多线程环境下崩溃

Log4cplus apis crashes in multithreading environment

本文关键字:崩溃 环境 多线程 api Log4cplus      更新时间:2023-10-16

我写了一个简单的程序来检查log4cplus api在多线程环境下完美工作的能力,但是当我运行时,它总是崩溃

请给出一些原因。我决定使用log4cplus api,因为网上大多数评论都说它是线程安全的。

我的测试源代码如下所示。

#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS     5
static Logger logger;
static void log4splus_api()
{
    logger = Logger::getInstance("database");
        LOG4CPLUS_WARN(logger, "This is a short: " << (short)-100);
        LOG4CPLUS_WARN(logger, "This is a unsigned short: " << (unsigned short)100);
    logger = Logger::getInstance("network");
    LOG4CPLUS_WARN(logger, "This is a short: " << (short)-100);
        LOG4CPLUS_WARN(logger, "This is a unsigned short: " << (unsigned short)100);
    logger = Logger::getInstance("utility");
    LOG4CPLUS_WARN(logger, "This is a short: " << (short)-100);
        LOG4CPLUS_WARN(logger, "This is a unsigned short: " << (unsigned short)100);
    logger = Logger::getInstance("server");
    LOG4CPLUS_WARN(logger, "This is a short: " << (short)-100);
        LOG4CPLUS_WARN(logger, "This is a unsigned short: " << (unsigned short)100);
    logger = Logger::getInstance("upgrade");
    LOG4CPLUS_WARN(logger, "This is a short: " << (short)-100);
        LOG4CPLUS_WARN(logger, "This is a unsigned short: " << (unsigned short)100);
}
void *testThread(void *threadid)
{
   long tid;
   tid = (long)threadid;
   cout << "ntestThread! Thread ID, " << tid << endl;
    while(true)
    {
        try
        {
            log4splus_api();
        }
        catch(...)
        {
            printf("nException occured...");
        }
    }
   pthread_exit(NULL);
}
int main ()
{
    initialize();
    PropertyConfigurator config("./logs.properties");
    config.configure();
   pthread_t threads[NUM_THREADS];
   int rc;
   int i;
   for( i=0; i < NUM_THREADS; i++ ){
      cout << "main() : creating thread, " << i << endl;
      rc = pthread_create(&threads[i], NULL, 
                          testThread, (void *)i);
      if (rc){
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

日志。属性文件如下

### logs.properties
# root logger
log4cplus.rootLogger=INFO,STDOUT
log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
# specific logger
log4cplus.logger.database=INFO, database
log4cplus.additivity.database=false
# specific logger
log4cplus.logger.network=INFO, network
log4cplus.additivity.network=false
# specific logger
log4cplus.logger.utility=INFO, utility
log4cplus.additivity.utility=false
# specific logger
log4cplus.logger.server=INFO, server
log4cplus.additivity.server=false
# specific logger
log4cplus.logger.upgrade=INFO, upgrade
log4cplus.additivity.upgrade=false

# appender that automatically rolls files
log4cplus.appender.database=log4cplus::RollingFileAppender
log4cplus.appender.database.File=database.log
log4cplus.appender.database.layout=log4cplus::PatternLayout
log4cplus.appender.database.layout.ConversionPattern=%D | %-5.5p | %-20.20c | %m|%n
log4cplus.appender.database.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.database.filters.1.LogLevelMin=DEBUG
log4cplus.appender.database.filters.1.LogLevelMax=FATAL
log4cplus.appender.database.filters.1.AcceptOnMatch=true
log4cplus.appender.database.filters.2=log4cplus::spi::DenyAllFilter
#log4cplus.appender.database.Schedule=DAILY
#log4cplus.appender.database.Append=false
log4cplus.appender.database.MaxBackupIndex=1
log4cplus.appender.database.MaxFileSize=1000KB
# appender that automatically rolls files
log4cplus.appender.network=log4cplus::RollingFileAppender
log4cplus.appender.network.File=network.log
log4cplus.appender.network.layout=log4cplus::PatternLayout
log4cplus.appender.network.layout.ConversionPattern=%D | %-5.5p | %-20.20c | %m|%n
log4cplus.appender.network.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.network.filters.1.LogLevelMin=DEBUG
log4cplus.appender.network.filters.1.LogLevelMax=FATAL
log4cplus.appender.network.filters.1.AcceptOnMatch=true
log4cplus.appender.network.filters.2=log4cplus::spi::DenyAllFilter
#log4cplus.appender.network.Schedule=DAILY
#log4cplus.appender.network.Append=false
log4cplus.appender.network.MaxBackupIndex=1
log4cplus.appender.network.MaxFileSize=1000KB
# appender that automatically rolls files
log4cplus.appender.utility=log4cplus::RollingFileAppender
log4cplus.appender.utility.File=utility.log
log4cplus.appender.utility.layout=log4cplus::PatternLayout
log4cplus.appender.utility.layout.ConversionPattern=%D | %-5.5p | %-20.20c | %m|%n
log4cplus.appender.utility.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.utility.filters.1.LogLevelMin=DEBUG
log4cplus.appender.utility.filters.1.LogLevelMax=FATAL
log4cplus.appender.utility.filters.1.AcceptOnMatch=true
log4cplus.appender.utility.filters.2=log4cplus::spi::DenyAllFilter
#log4cplus.appender.utility.Schedule=DAILY
#log4cplus.appender.utility.Append=false
log4cplus.appender.utility.MaxBackupIndex=1
log4cplus.appender.utility.MaxFileSize=1000KB
# appender that automatically rolls files
log4cplus.appender.server=log4cplus::RollingFileAppender
log4cplus.appender.server.File=server.log
log4cplus.appender.server.layout=log4cplus::PatternLayout
log4cplus.appender.server.layout.ConversionPattern=%D | %-5.5p | %-20.20c | %m|%n
log4cplus.appender.server.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.server.filters.1.LogLevelMin=DEBUG
log4cplus.appender.server.filters.1.LogLevelMax=FATAL
log4cplus.appender.server.filters.1.AcceptOnMatch=true
log4cplus.appender.server.filters.2=log4cplus::spi::DenyAllFilter
#log4cplus.appender.server.Schedule=DAILY
#log4cplus.appender.server.Append=false
log4cplus.appender.server.MaxBackupIndex=1
log4cplus.appender.server.MaxFileSize=1000KB
# appender that automatically rolls files
log4cplus.appender.upgrade=log4cplus::RollingFileAppender
log4cplus.appender.upgrade.File=upgrade.log
log4cplus.appender.upgrade.layout=log4cplus::PatternLayout
log4cplus.appender.upgrade.layout.ConversionPattern=%D | %-5.5p | %-20.20c | %m|%n
log4cplus.appender.upgrade.filters.1=log4cplus::spi::LogLevelRangeFilter
log4cplus.appender.upgrade.filters.1.LogLevelMin=DEBUG
log4cplus.appender.upgrade.filters.1.LogLevelMax=FATAL
log4cplus.appender.upgrade.filters.1.AcceptOnMatch=true
log4cplus.appender.upgrade.filters.2=log4cplus::spi::DenyAllFilter
#log4cplus.appender.upgrade.Schedule=DAILY
#log4cplus.appender.upgrade.Append=false
log4cplus.appender.upgrade.MaxBackupIndex=1
log4cplus.appender.upgrade.MaxFileSize=1000KB

你有一个全局变量,所有线程同时使用和共享,没有保护。考虑一下,如果一个线程开始给变量赋值,而另一个线程正在进行日志调用,那么将会发生什么。

是的!logger应为log4splus_api()中的自变量,或TLS变量