2014-01-13 3 views
1

시뮬레이터 (ns3)를 사용하고 있는데, 주 ​​응용 프로그램에서 일부 파일을 다운로드하기 위해 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

대부분의 경우 문제는 파일에 동시에 추가하려고하는 스레드가 여러 개있는 것입니다. 좋은 일은 아무것도 할 수 없습니다.

내 제안에는 로깅 스레드와 대기열이 있습니다. 쓰레드가 로그에 쓰고 싶을 때, 메시지를 로깅 큐에 넣기 만하면된다. 로깅 스레드는 대기열에서 읽고 로그 파일에 기록합니다.

물론 동시 요청에 의해 손상되지 않도록 동기화를 추가하거나 해당 동기화를 이미 처리 한 동시 대기열을 찾아야합니다.

관련 문제