pthread 자원 해제에 대한 이야기(pthread_detach, pthread_attr_setdetachstate)

일반적으로 pthread_create를 통해서 쓰레드가 생성되고 다 사용된 쓰레드는 해당 쓰레드를 호출한 곳에서 pthread_join을 통하여 해당 쓰레드의 자원을 해제하여 종료하는 흐름을 갖는다. 만약 생성된 쓰레드를 pthread_join으로 처리하지 않는다면 아무리 쓰레드가 종료되었다고 해도 자원이 반환되지 않는다. 이렇게 남겨진 자원은 메모리릭으로 간주되기 때문에 pthread_join은 쓰레드간의 동기작업과 자원 해제를 위해 필수적이다.


하지만 pthread_join을 하지 않고도, 생성된 쓰레드가 종료될 때 알아서 자원을 시스템에게 반환하는 detach 옵션이 있다.
말 그대로 독립적으로 운용하게 하라라는 의미로 생각되며(물론 자원적인면에서만), detach 옵션을 주는 방법은 두가지가 있다.


첫번째로,  pthread_create할 때 생성될 쓰레드 속성값에 detach를 설정하여 새로 생성될 쓰레드는 독립적으로 자원을 해제하도록 하게 할 수 있다.

 #include <pthread.h>

 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
 int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);


아래와 같이 pthread_attr_t에 detach 옵션을 먼저 설정하고, 쓰레드를 생성하는 시점인 pthread_create에 설정된 pthread_attr_t를 인자로 넘겨주어 detach로 쓰레드가 생성되도록 한다.

  pthread_t thread;
  pthread_attr_t attr;

  if( pthread_attr_init(&attr) != 0 )
    return 1;

  if( pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0 )
    return -1;

  if( pthread_create(&thread,&attr, &test_thread, NULL ) != 0 )
    return -1;

  if( pthread_attr_destroy(&attr) != 0 )
    return -1;

  /*
   * while (1)
   * {
   *  main thread logic...
   * }
   */



두번째는
, 이미 생성된 쓰레드에게 detach 옵션을 주어 독립적으로 자원을 반환 하도록 하는 방법이다.

 #include <pthread.h>
 int pthread_detach(pthread_t thread);



아래와 같이 thread를 생성 한 후에 detach 옵션을 줄 수 있다.
  if( pthread_create(&thread,&attr, &test_thread, NULL ) != 0 )
    return 1;

  pthread_detach(thread);



이 옵션을 몰랐을 때는, pthread_join을 해주는 쓰레드를 만들어서 모든 쓰레드를 모니터링을 하게 해야 해나 하는 구상까지 했었는데 간단하게 해결할 수 있는 문제였다.

참고적으로 첫번째 방법을 추천한다. 쓰레드의 속성을 운용중에 변경되는것은 로직상의 혼란을 줄 수 있고, 거의 그럴일은 없겠지만 detach 옵션을 주기전에 이미 해당 쓰레드가 끝나버릴 수도 있을 가능성이 있기 때문이다.



Tags

Read Next

  1. 잘이해가 되지 않는 부분이 생겼는데요,
    어떤경우에 detach를 해주기 전에 스래드가 종료되는 상황이 발생하나요?

    • 마지막 문구 때문에 질문하신거 같네요. 결론은 logic에 따라 다릅니다.
      thread의 할일이 detach 해주기전에 끝나버리게 프로그래밍 되어 있다면 가능한 일입니다. 거의 이렇게 코드를 작성하지 때문에 이러한 일은 일어나지 않겠지요.

      하지만, 혼자서 개발하지 않은 상황에서는 이런 예외사항이 발생할 가능성이 1%라도 있으며, 그 가능성이 발생하지 않도록 미연의 방지하는게 좋다라는 생각으로 첫번째 방법을 추천드린것입니다.

  2. 혹시 궁금한게 있는데요.

    detach()를 사용하여 스레드 분리를 시킬 때
    꼭 메인스레드(스레드를 만든 곳)에서 detach()를 호출해야 하는지?
    아니면 생성된 스레드 내부에서 detach()를 호출해도 상관 없는 것인지 궁금하네요.
    일단 생성된 스레드 내부에서 자기 자신을 detach할 경우를 테스트를 해보면 정상적으로 동작은 하더라구요.
    이럴경우 문제될 부분은 없는지 의견이 궁금합니다.
    감사합니다.

    • 시도해보지는 않았지만, detach 함수 인자로 들어가는 thread를 잘 넣어주면 불가능할꺼 같진 않습니다. 리소스 릭이 발생하지 않는다면 문제는 없을 것으로 보이지만, 명시적으로 생성 시점에서 알려주는게 코드를 읽기 더 쉬울꺼 같아요.

*

*