Как войти в файл с помощью потоков

Я использую симулятор (ns3), в моем основном приложении я выделяю несколько приложений с именем Consumer для загрузки некоторых файлов.
В этом классе (Consumer), когда я заканчиваю скачивать файл, я хочу зарегистрировать в нем некоторую статистику, поэтому я реализовал эти функции (см. Ниже), используя потоки, что, если у меня в основном есть небольшое количество потребителей не являются проблемами, но с очень большим числом я не могу открыть файл журнала, когда я вызываю функцию, которая создает поток.

//consumer.cc
void
Consumer::OnData (Ptr<const Data> contentObject)
{
//do something
if (...)
{
int a = Consumer::create_thread();
std::string s = "foo";
Consumer::Log(s);
}
}

int Consumer::create_thread(){
int rc = pthread_create(&logger, NULL, &Consumer::runFunc, (void*) this); //logger is declared in consumer.h as pthread_t logger;
if(rc) printf("ERROR; return code from pthread_create() is %d\n", rc);
sem_init(&queueSem, 0, 0);
pthread_mutex_init(&mutex, NULL);
//isLogActive = true;
myfile.open ("ret.txt", std::ios::app);
if(!myfile.is_open())
std::cout << "Error opening the log file...";
return 1;
}

void Consumer::run_t(){
for(;;)
{
sem_wait(&queueSem);
//if(!isLogActive)
//  break;
pthread_mutex_lock (&mutex);
myfile << queue.front();
queue.pop();
pthread_mutex_unlock (&mutex);
myfile.flush();
}
while(!queue.empty())
{
std::cout<<queue.front()<<std::endl;
myfile << queue.front();
queue.pop();
}
if(myfile.is_open())
{
myfile.close();
std::cout << "File Ret closed.\n";
}
else
std::cerr << "Calcolo error.\n";
pthread_exit(NULL);
}

void * Consumer::runFunc(void * self){

((Consumer*)self)->run_t();
return NULL;

}

void Consumer::Log(std::string toLog)
{

ss.str("");
ss.clear();
ss << toLog << "\n";
pthread_mutex_lock (&mutex);
queue.push(ss.str());
pthread_mutex_unlock (&mutex);
sem_post(&queueSem);
}

Как вы думаете, это проблема? И как я мог это исправить?

1

Решение

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

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

Конечно, вам придется добавить некоторую синхронизацию в очередь, чтобы она не была повреждена одновременными запросами, или найти параллельную очередь, которая уже обрабатывает эту синхронизацию для вас.

1

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

Других решений пока нет …

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