0

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

请给出一些,为什么会这样。我决定使用 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 文件如下所示

### 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
4

1 回答 1

0

那么你有一个全局变量,所有线程同时使用和共享,没有保护。想想如果一个线程开始分配给变量会发生什么,被切换到另一个正在日志调用中间的线程。

是的!logger应该是自动变量log4splus_api(),或 TLS 变量。

于 2014-08-25T08:53:19.873 回答