2014-10-17 3 views
0

이상한 문제가 있습니다.주 프로세스 -> pthread -> fork + execvp

때로는 내 프로그램을 충분히 오래 실행하면 프로그램이 두 개 실행되는 것을 볼 수 있습니다. 두 번째는 첫 번째 자식 프로세스입니다. 두 번째 부모 PID는 첫 번째 자식 PID입니다.

나는 내 코드에 포크가 있다는 것을 깨달았는데, 그 이유는 단지 두 개의 복사본을 실행할 수 있기 때문이다. 그렇지 않으면 결코 내 프로그램의 복사본 두 개를 실행할 수 없다.

매우 드물게 발생하지만 일어납니다.

주요 프로그램이 이벤트를 가져오고는 pthread를 생성합니다 다음과 같이

아키텍처입니다. 그 스레드에서 나는 어떤 처리를하고 어떤 결과를 기반으로 execvp가 바로 따라 간다.

나는 pthread에서 포크를 호출하는 것이 가장 좋지 않지만 내 설계에서는 주 프로세스가 많은 이벤트를 가져오고 모든 이벤트에서 병렬로 작업하는 유일한 방법은 pthread를 사용하는 것이 었습니다. 각 pthread는 일부 처리를 수행하고 어떤 경우에는 다른 프로그램을 호출해야합니다 (execvp를 사용합니다). 이후로 나는 다른 프로그램을 호출해야했기 때문에 포크를 사용해야했다.

나는 결국 스레드 컨텍스트에서 포크를 호출하기 때문에 여러 스레드가 병렬로 fork + execvp를 호출하고 "어떻게 든"결과를 얻을 수 있는지 궁금해졌다. 두 개의 사본이 만들어집니다.

실제로 + forkv + execvp를 호출하는 스레드가 하나 밖에 없기 때문에 뮤텍스가있는 fork + execvp를 보호하면 도움이됩니다.

그러나 내가 포크 + excvp 전에 뮤텍스를 가져 가면 언제 해제해야하는지 알지 못합니다.

여기에 도움을 주시면 감사하겠습니다.

포크 + execvp는 않습니다

스레드 코드 - 너희들이 문제가 자리 수 있습니다 경우 : main.c의에서

status = pthread_create(&worker_thread, tattr, 
           do_some_useful_work, some_pointer); 

[클립] 나는 보았다

void *do_some_useful_work (void * arg) 
    { 
      /* Do some processing and fill pArguments array */ 

      child_pid = fork(); 

      if (child_pid == 0) 
      { 
       char *temp_log_file; 

       temp_log_file = (void *) malloc (strlen(FORK_LOG_FILE_LOCATION) + 
             strlen("/logfile.") + 8); 

       sprintf (temp_log_file, "%s/logfile.%d%c", FORK_LOG_FILE_LOCATION, getpid(),'\0'); 

       /* Open log file */ 
       int log = creat(temp_log_file, 0777); 
       /* Redirect stdout to log file */ 
       close(1); 
       dup(log); 
       /* Redirect stderr to log file */ 
       close(2); 
       dup(log); 

       syslog(LOG_ERR, "Opening up log file %s\n", temp_log_file); 

       free (temp_log_file); 

       close (server_sockets_that_parent_is_listening_on); 

       execvp ("jazzy_program", pArguments); 

     } 

     pthread_exit (NULL); 

     return NULL; 
    } 

을 이 코드를 통해 나는 포크를하고 execvp를하지 않을 이유가 없다. 그래서 내 마음에 오는 유일한 시나리오는 다중 스레드가 실행되고 포크 + execvp를 호출한다는 것이다. 이 때로는 내 메인 프로그램의 복사본 두 개가 실행됩니다.

+0

제공하신 코드로는 문제를 진단하거나 재현하기에 충분하지 않지만 몇 가지 아이디어로 답변 해 드렸습니다. –

답변

1

execvp이 어떤 이유로 (프로세스가 너무 많거나 메모리가 부족한 등) 오류가 발생하는 경우 오류를 처리하지 못합니다. 대신 스레드의 분기 된 복사본이 계속 실행됩니다. 이 프로세스에서 pthread_exit (또는 비동기 신호 이외의 비보호) 함수를 호출하면 정의되지 않은 동작이 발생하므로 제대로 종료되지 않고 중단되거나 예상하지 못한 결과가 발생할 수 있습니다. 이런 일이 발생하면 항상 exec 오류를 확인하고 즉시 _exit(1) 또는 이와 유사한 것이 있는지 확인해야합니다. 또한 이것은 아마도 문제가 아니지만 malloc을 비동기 신호가 아니기 때문에 멀티 스레딩 프로세스에서 분기 한 후에는 안전하지 않습니다.

관련 문제