Log4cplus apis падает в многопоточной среде

Я написал простую программу для проверки способности log4cplus apis отлично работать в многопоточной среде, но когда я запускаю, он падает все время.

Пожалуйста, дайте немного, почему это происходит. Я решил использовать log4cplus apis, потому что большая часть обзора в сети говорит, что это потокобезопасно.

мой тестовый исходный код приведен ниже.

#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

0

Решение

Ну, у вас есть одна глобальная переменная, которая используется и совместно используется всеми потоками одновременно, без защиты. Подумайте о том, что произойдет, если один поток начнет присваивать переменную, переключится на другой поток, который находится в середине вызова регистрации.

Да! logger должна быть автоматическая переменная в log4splus_api()или переменная TLS.

0

Другие решения


По вопросам рекламы [email protected]