출처 : http://krunivs.tistory.com/43
에 보면 나타나있습니다.
회사 AIX 는 아래와 같군요
어떻게 커널이 컴파일 되었는지 모르면 아래와 같은 코드로 출력을 해볼 수도 있습니다.
제가 현재 사용하는 서버에서는 32768 개의 동시 쓰레드를 생성할 수 있습니다.
과연??? 한번 아래와 같은 코드로 출력을 해보았습니다.
출력은 아래와 같이 됩니다.
당연한 결과라 사료됩니다. 쓰레드 Function 이 바로 종료가 되지만, CPU 관점에서 본다면 바로 종료가 될수는 없으리라 여겨집니다.
이번엔 아래와 같이 코드를 수정했씁니다.
결과는 아래와 같습니다.
예상대로 끊임없이 돕니다.
이번엔 바로 종료되는 쓰레드가 아닌 루프를 돌렸습니다.
결과입니다.
detatch 를 해줘봐야 종료가 안되는 쓰레드이니 자원반납의 의미가 없습니다.
그럼 쓰레드 Function 이 루프가 없었던 경우, detach 한 경우와 하지 않은 경우에서 detach 를 한경우는 (끊임없이 쓰레드 생성을 하는 것으로 봐서) 쓰레드의 종료가 일어 나면서 사용했던 메모리(thread stack size) 를 반납을 해주어서 끊임없이 생성이 가능 했다고 할 수 있습니다.
Stevens 가 쓴 Advanced Programming in the UNIX Environment 에서 보면 쓰레드 반납을 위해 pthread_join, 혹은 pthread_detach 를 꼭해주어야 한다고 나와 있습니다.
일례로 쓰레드 Function 에서 pthread_exit() 를 명시적으로 호출해준다면..
이코드 역시 쓰레드 생성중 Resource 부족으로 프로그램이 종료됩니다.
pthread_cancel() 역시 마찬가지입니다.
쓰레드 생성시 join 을 호출 하지 않을 거라면(일반적인 멀티 쓰레드 서버 어플리케이션이라면 join 호출할일이 그다지 없습니다) 항상 detach 를 해주시는게 도움이 됩니다.
보통 쓰레드를 생성하실경우 아래와 같이 하시면 도움이 될듯합니다.
사족으로 쓰레드의 스택 사이즈가 얼마나 먹길래 몇개 생성도 안해서 죽어버리는지 알고 싶으시면 (시스템에따라 1000~500 개 under 일 경우가 대부분입니다)
한 프로세스 혹은 시스템에서 만들 수 있는 쓰레드의 갯수(동시작업)는 주로
/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
#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);
}
{
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
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);
pthread_detach(thread);
결과는 아래와 같습니다.
Thread : 101420
Thread : 101421
Thread : 101422
.....
Thread : 101421
Thread : 101422
.....
예상대로 끊임없이 돕니다.
이번엔 바로 종료되는 쓰레드가 아닌 루프를 돌렸습니다.
void* threadFunction(void*)
{
cout << "Thread : " << ::count++ << endl;
void* retr;
while (true)
{
sleep(1);
}
return NULL;
}
{
cout << "Thread : " << ::count++ << endl;
void* retr;
while (true)
{
sleep(1);
}
return NULL;
}
결과입니다.
.....
Thread : 2152
Thread : 2153
Thread : 2154
Thread : 2155
Resource temporarily unavailable
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);
}
{
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");
}
}
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 일 경우가 대부분입니다)
'리눅스 서버에 대해서 > 솔라리스(UNIX) 관련' 카테고리의 다른 글
[솔라리스] tar와 gzip를 한번에 하기 (0) | 2013.02.01 |
---|---|
VM ware 설정하기 (0) | 2013.01.15 |
어플리케이션 개발자를 위한 솔라리스와 리눅스 차이점 (0) | 2013.01.10 |
솔라리스에서 파일 첨부 (0) | 2013.01.09 |
UNIX 뮤텍스 (0) | 2013.01.09 |