출처 : http://krunivs.tistory.com/43

한 프로세스 혹은 시스템에서 만들 수 있는 쓰레드의 갯수(동시작업)는  주로

/usr/include/sys/pthread.h

에 보면 나타나있습니다.

회사 AIX 는 아래와 같군요

#ifdef _LARGE_THREADS
#define MAXTHREADS  32767       /* max number of additional threads   */
                    /* per process.  This number + 1 must */
                    /* be a multiple of 128           */
#else
#define MAXTHREADS  512     /* max number of threads per process, */
                    /* MUST be a multiple of 128, assuming*/
                    /* uthread is padded to 32 bytes and a*/
                    /* page is 4096-byte long         */
#endif

어떻게 커널이 컴파일 되었는지 모르면 아래와 같은 코드로 출력을 해볼 수도 있습니다.

cout << sysconf(_SC_THREAD_THREADS_MAX) << endl;

제가 현재 사용하는 서버에서는 32768 개의 동시 쓰레드를 생성할 수 있습니다.

과연???  한번 아래와 같은 코드로 출력을 해보았습니다.

void* threadFunction(void*)
{
    cout << "Thread : " << ::count++ << endl;
    return NULL;
}

int main()
{
    while (true)
    {
        pthread_t thread;
        pthread_attr_t attr;
   
        pthread_attr_init(&attr);

        int ret = pthread_create(&thread, &attr, threadFunction, NULL);
    
        if (ret != 0)
        {
            cout << strerror(ret) << endl;
            return 0;
        }

        usleep(1000);
    }

출력은 아래와 같이 됩니다. 

.......
Thread : 2304
Thread : 2305
Thread : 2306
Thread : 2307
Thread : 2308
Resource temporarily unavailable

당연한 결과라 사료됩니다. 쓰레드 Function 이 바로 종료가 되지만, CPU 관점에서 본다면 바로 종료가 될수는 없으리라 여겨집니다.

이번엔 아래와 같이 코드를  수정했씁니다.

        int ret = pthread_create(&thread, 0, threadFunction, NULL);
        pthread_detach(thread);

결과는 아래와 같습니다. 
Thread : 101420
Thread : 101421
Thread : 101422
.....

예상대로 끊임없이 돕니다.

이번엔 바로 종료되는 쓰레드가 아닌 루프를 돌렸습니다.

void* threadFunction(void*)
{
    cout << "Thread : " << ::count++ << endl;

    void* retr;
    while (true)
    {
        sleep(1);
    }
    return NULL;
}

결과입니다.

.....
Thread : 2152
Thread : 2153
Thread : 2154
Thread : 2155
Resource temporarily unavailable

detatch 를 해줘봐야 종료가 안되는 쓰레드이니 자원반납의 의미가 없습니다.

그럼 쓰레드 Function 이 루프가 없었던 경우, detach 한 경우와 하지 않은 경우에서 detach 를 한경우는 (끊임없이 쓰레드 생성을 하는 것으로 봐서) 쓰레드의 종료가 일어 나면서 사용했던 메모리(thread stack size) 를 반납을 해주어서 끊임없이 생성이 가능 했다고 할 수 있습니다.

Stevens 가 쓴 Advanced Programming in the UNIX Environment 에서 보면 쓰레드 반납을 위해  pthread_join, 혹은 pthread_detach 를 꼭해주어야 한다고 나와 있습니다.

일례로 쓰레드 Function 에서 pthread_exit() 를 명시적으로 호출해준다면..

void* threadFunction(void*)
{
    cout << "Thread : " << ::count++ << endl;
    pthread_exit((void*) 1);
}

이코드 역시 쓰레드 생성중 Resource 부족으로 프로그램이 종료됩니다.
pthread_cancel() 역시 마찬가지입니다. 

쓰레드 생성시 join 을 호출 하지 않을 거라면(일반적인 멀티 쓰레드 서버 어플리케이션이라면 join 호출할일이 그다지 없습니다) 항상 detach 를 해주시는게 도움이 됩니다.

보통 쓰레드를 생성하실경우 아래와 같이 하시면 도움이 될듯합니다.

typedef void*                   (*startFunc)(void*);
void startThread(startFunc run, void* arg)
{
    pthread_t       t;
    pthread_attr_t  attr;

    if (pthread_attr_init(&attr) != 0 ||
        pthread_create(&t, &attr, run, arg) != 0 ||
        pthread_attr_destroy(&attr) != 0 ||
        pthread_detach(t) != 0)
    {
//        CRITICAL("Can't Start Thread");
    }
}


사족으로 쓰레드의 스택 사이즈가 얼마나 먹길래 몇개 생성도 안해서 죽어버리는지 알고 싶으시면 (시스템에따라 1000~500 개 under 일 경우가 대부분입니다)


+ Recent posts