레드햇 9.0에서 쓰레드를 255개 이상 생성시켜 보신분...

sisap의 이미지

안녕하세요?
쓰레드 초보입니다. -_-;;

Pentium 4, 700Mhz, 512M, 리눅스 9.0을 쓰고 있습니다.
커널은 2.4.20-8 이고요..

기존의 fork를 쓰레드로 전환 중인데, fork는 머 한 1000개 정도는 그냥 되는데, 쓰레드는 250 몇개 정도에서 더이상 생성하지를 못하네요.
쓰레드 내부에서는 테스트 하느라고 모두 코멘트 처리를 해 놔서 별 짓 안합니다. 그냥 루프만 돌죠..

255개 정도를 넘어가면서는 pthread_create에서 리턴값이 12가 나와서 뒤져보니 무슨 에러인지/usr/include/asm/errno.h파일에서 뒤져보니
#define ENOMEM 12 /* Out of memory */

요렇게.. Out of memory라고 나오네요.

게시판을 뒤져보며 확인해본 시스템 설정상으로는..
/proc/sys/kernel/threads-max
8191

/usr/include/bits/local_lim.h:
#define PTHREAD_THREADS_MAX 16384

위의 두 값이 왜 틀리게 되어 있는지는 모르겠지만 하여간, Out of memory에러 넘버도 그렇고.. THREADS_MAX값들을 봐서도 메모리 문제 인것같아서 메모리를 체크해 봤습니다.

255개 쓰레드를 생성하고도 메모리는 5메가 정도밖에 안줄더군요.
60메가 정도의 여유 메모리가 있는데, 이건 시스템 전체 메모리니까.. 별 상관은 없을듯하고.. 프로세스당 사용할수있는 메모리 제한에서 걸린 듯 싶어 게시판을 더 뒤져보니..
STACK_SIZE를 조정할수 있다던데..

어떤분은 리눅스 7.x버젼인가에서 pthread_attr_init옵션을 어떻게 줘서 1000개 이상 생성이 되었다고도 하시던데..

저는 오라클 9.1.0이던가? 를 설치 해볼려고 glibc관련 rpm 몇개를 다음과 같은 rpm들로 다운 그레이드 한 상태입니다.
glib-2.3.2-5.i686.rpm glibc-common-2.3.2-5.i386.rpm
glibc-devel-2.3.2-5.i386.rpm

혹시 이것때문에 문제가 있는건 아닌지..

하여간, 조금이라도 도움이 될 수 있는 글이라도 남겨주시면 감사하겠습니다.

참, 모두 새해 복 많이 받이시고요~

추가> 으음.. 이거 계정 환경이 머가 틀린지 pthread_create에서 리턴값이 11이 나오는 계정이 있고 12가 나오는 계정이 있네요..
이건 또 머냐.. 좀 더 디벼 봐야 겠네요..
하여간, 답글 많이좀 달아 주세요 -_-;;

sisap의 이미지

혹시 이 문제에 관심 있으신분, 아래 코드를 자신의 리눅스 9.0 머신에서 돌려 봐주실수 있나요.. 몇개까지 쓰레드가 생성되는지..

컴파일은 gcc -lpthread -o thread-limit thread-limit.c 요렇게..

/* compile with:   gcc -lpthread -o thread-limit thread-limit.c */
/* originally from: http://www.volano.com/linuxnotes.html */
                                                                                                                     
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
                                                                                                                     
#define MAX_THREADS 10000
int i;
                                                                                                                     
void run(void) {
  char c;
  if (i < 10)
    printf("Address of c = %u KB\n", (unsigned int) &c / 1024);
  sleep(60 * 60);
}
                                                                                                                     
int main(int argc, char *argv[]) {
  int rc = 0;
  //system("cat /proc/meminfo");
  pthread_t thread[MAX_THREADS];
  printf("Creating threads ...\n");
  for (i = 0; i < MAX_THREADS && rc == 0; i++) {
    rc = pthread_create(&(thread[i]), NULL, (void *) &run, NULL);
    if (rc == 0) {
      pthread_detach(thread[i]);
      if ((i + 1) % 100 == 0)
        printf("%i threads so far ...\n", i + 1);
    }
    else {
      //system("cat /proc/meminfo");
      printf("Failed with return code %i creating thread %i.\n",
             rc, i + 1);
        }
  }
                                                                                                                     
  //for (;;) sleep(10);
  exit(0);
}

부탁 드리겠습니다~

indizarm의 이미지

Creating threads ...
Address of c = 1056974 KB
Address of c = 1065166 KB
Address of c = 1073357 KB
Address of c = 1090761 KB
Address of c = 1098953 KB
Address of c = 1107145 KB
Address of c = 1115337 KB
Address of c = 1123529 KB
Address of c = 1131721 KB
Address of c = 1139913 KB
100 threads so far ...
200 threads so far ...
Failed with return code 12 creating thread 255.

커널은 2.4.20-8smp

이유는 나도 모름. 며느리도 모름... (아차차 나는 총각이었지~)
그냥 긁어다가 실행만 시켜봄

What a Cool Days!!!

godyang의 이미지

안녕하세요?

전 데비안 사지에서 2.6.0-test11 커널을 사용하는데 비슷한 결과입니다. --;
혹시나 싶어서 솔라리스 머신에도 돌려봤는데, 거기에는 잘 돌아가네요.

아무래도 뭔가 설정이 있는 듯 한데... 저 역시 해결책은 잘...

godyang@myhost:~/prog/test$ uname -a
Linux myhost 2.6.0-test11 #1 Fri Nov 28 13:26:23 KST 2003 i686 GNU/Linux
godyang@myhost:~/prog/test$ cat /proc/sys/kernel/threads-max 
4095
godyang@myhost:~/prog/test$ ./thread-limit 
Creating threads ...
Address of c = 1058202 KB
Address of c = 1066394 KB
Address of c = 1074586 KB
Address of c = 1082778 KB
Address of c = 1090970 KB
Address of c = 1099162 KB
Address of c = 1107354 KB
Address of c = 1115546 KB
Address of c = 1123738 KB
Address of c = 1131930 KB
100 threads so far ...
200 threads so far ...
Failed with return code 12 creating thread 256.
godyang@myhost:~/prog/test$

godyang@aaa:~/prog/test$ uname -a
SunOS aaa 5.7 Generic_106541-16 sun4u sparc SUNW,Ultra-60
godyang@aaa:~/prog/test$ ./thread-limit 
Creating threads ...
100 threads so far ...
200 threads so far ...
300 threads so far ...
400 threads so far ...
500 threads so far ...
600 threads so far ...
700 threads so far ...
800 threads so far ...
900 threads so far ...
1000 threads so far ...
1100 threads so far ...
1200 threads so far ...
1300 threads so far ...
1400 threads so far ...
1500 threads so far ...
1600 threads so far ...
1700 threads so far ...
1800 threads so far ...
1900 threads so far ...
2000 threads so far ...
2100 threads so far ...
2200 threads so far ...
2300 threads so far ...
2400 threads so far ...
2500 threads so far ...
2600 threads so far ...
2700 threads so far ...
2800 threads so far ...
2900 threads so far ...
3000 threads so far ...
3100 threads so far ...
3200 threads so far ...
3300 threads so far ...
Failed with return code 11 creating thread 3400.
godyang@aaa:~/prog/test$ 
fibonacci의 이미지

저는 데비안 sid, kernel-2.4.18, 커널 컴파일시 SMP, 4G까지 메모리 사용가능하도록 컴파일 했고요..
기계 사양은 Xeon 700Mhz x 4, 4G 메모리 정도네요.

Creating threads ...
Address of c = 3137534 KB
Address of c = 3135486 KB
Address of c = 3133438 KB
Address of c = 3131390 KB
Address of c = 3129342 KB
Address of c = 3127294 KB
Address of c = 3125246 KB
Address of c = 3123198 KB
Address of c = 3121150 KB
Address of c = 3119102 KB
100 threads so far ...
200 threads so far ...
300 threads so far ...
400 threads so far ...
500 threads so far ...
600 threads so far ...
700 threads so far ...
800 threads so far ...
900 threads so far ...
1000 threads so far ...
1100 threads so far ...
1200 threads so far ...
1300 threads so far ...
1400 threads so far ...
1500 threads so far ...
Failed with return code 11 creating thread 1533.

참고로 지금 제 서버의 메모리 상태입니다.. used가 적었다면, 더 좋았을뻔 했을텐데요 ^^;
~> free -m
total used free shared buffers cached
Mem: 3620 1763 1857 0 36 1366
-/+ buffers/cache: 360 3260
Swap: 517 0 517

No Pain, No Gain.

fox9의 이미지

laputa:~/program>uname -a
FreeBSD laputa 5.2-CURRENT FreeBSD 5.2-CURRENT #9: Sat Dec 20 11:24:58 KST 2003     root@laputa:/usr/obj/usr/src/sys/MY  i386

laputa:~/program>./thread-test
...
8700 threads so far ...
8800 threads so far ...
8900 threads so far ...
9000 threads so far ...
9100 threads so far ...
9200 threads so far ...
9300 threads so far ...
9400 threads so far ...
9500 threads so far ...
9600 threads so far ...
9700 threads so far ...
9800 threads so far ...
9900 threads so far ...
10000 threads so far ...

10000개가 되어 버리네요 @.@
예전에 bbs.kldp.org가 생기기 이전의 kldp.org의 게시판에 위와 같은 문제점이 있어서 토론이 오고 간적이 있는데 그때의 게시판을 볼 방법이 없는지. :shock:

그때는 pthread_detatch와 pthread_attr_* 류의 함수등으로 설정해서 한듯 합니다
기억은 안나고... :(

whitekid의 이미지

Creating threads ...
100 threads so far ...
200 threads so far ...
300 threads so far ...
400 threads so far ...
500 threads so far ...
600 threads so far ...
700 threads so far ...
800 threads so far ...
900 threads so far ...
1000 threads so far ...
1100 threads so far ...
1200 threads so far ...
1300 threads so far ...
1400 threads so far ...
1500 threads so far ...
1600 threads so far ...
1700 threads so far ...
1800 threads so far ...
1900 threads so far ...
2000 threads so far ...
2100 threads so far ...
2200 threads so far ...
2300 threads so far ...
2400 threads so far ...
2500 threads so far ...
2600 threads so far ...
2700 threads so far ...
2800 threads so far ...
2900 threads so far ...
3000 threads so far ...
3100 threads so far ...
3200 threads so far ...
3300 threads so far ...
3400 threads so far ...
3500 threads so far ...
3600 threads so far ...
3700 threads so far ...
3800 threads so far ...
3900 threads so far ...
4000 threads so far ...
4100 threads so far ...
4200 threads so far ...
4300 threads so far ...
4400 threads so far ...
4500 threads so far ...
4600 threads so far ...
4700 threads so far ...
4800 threads so far ...
4900 threads so far ...
5000 threads so far ...
5100 threads so far ...
5200 threads so far ...
5300 threads so far ...
5400 threads so far ...
5500 threads so far ...
5600 threads so far ...
5700 threads so far ...
5800 threads so far ...
5900 threads so far ...
6000 threads so far ...
6100 threads so far ...
6200 threads so far ...
6300 threads so far ...
6400 threads so far ...
6500 threads so far ...
6600 threads so far ...
6700 threads so far ...
6800 threads so far ...
6900 threads so far ...
7000 threads so far ...
7100 threads so far ...
7200 threads so far ...
7300 threads so far ...
7400 threads so far ...
7500 threads so far ...
7600 threads so far ...
7700 threads so far ...
7800 threads so far ...
7900 threads so far ...
8000 threads so far ...
8100 threads so far ...
8200 threads so far ...
8300 threads so far ...
8400 threads so far ...
8500 threads so far ...
8600 threads so far ...
8700 threads so far ...
8800 threads so far ...
8900 threads so far ...
9000 threads so far ...
9100 threads so far ...
9200 threads so far ...
9300 threads so far ...
9400 threads so far ...
9500 threads so far ...
9600 threads so far ...
9700 threads so far ...
9800 threads so far ...
9900 threads so far ...
10000 threads so far ...

[whitekid@c2 whitekid]$ uname -a
FreeBSD XXX.com 4.9-RELEASE-p1 FreeBSD 4.9-RELEASE-p1 #1: Thu Dec 25 19:19:50 KST 2003 root@XXX.com:/usr/obj/usr/src/sys/C2 i386

What do you want to eat?

andrea0705의 이미지

Creating threads ...
Address of c = 1058414 KB
Address of c = 1066606 KB
Address of c = 1074798 KB
Address of c = 1082990 KB
Address of c = 1091182 KB
Address of c = 1099374 KB
100 threads so far ...
200 threads so far ...
Failed with return code 11 creating thread 256.

Redhat AS2.0에서 테스트 한 값임.

함 해보자.. 열심히..

bigdog의 이미지

메모리 관련 설정은 바꾼것없고요.
결과는 다음과 같네요.

smallcat:/export/home/smallcat# ./thread-limit
Creating threads ...
100 threads so far ...
200 threads so far ...
300 threads so far ...
400 threads so far ...
500 threads so far ...
600 threads so far ...
700 threads so far ...
800 threads so far ...
900 threads so far ...
1000 threads so far ...
1100 threads so far ...
1200 threads so far ...
1300 threads so far ...
1400 threads so far ...
1500 threads so far ...
1600 threads so far ...
1700 threads so far ...
1800 threads so far ...
1900 threads so far ...
2000 threads so far ...
2100 threads so far ...
2200 threads so far ...
2300 threads so far ...
2400 threads so far ...
2500 threads so far ...
2600 threads so far ...
2700 threads so far ...
2800 threads so far ...
2900 threads so far ...
3000 threads so far ...
3100 threads so far ...
3200 threads so far ...
3300 threads so far ...
3400 threads so far ...
3500 threads so far ...
3600 threads so far ...
3700 threads so far ...
3800 threads so far ...
3900 threads so far ...
4000 threads so far ...
Failed with return code 11 creating thread 4076.

sisap의 이미지

이렇게 많은 분들이 수고를 해주시다뉘.. 먼저 감사 말씀부터 드려야 겠네요. 꾸벅~ 넘 감사드리고요..

예.. 먼저 쭉 살펴보니.. 결국 OS마다 약간의 차이를 보이면서 돌아가는 넘들도 있고 하네요. 근데 결국은 레드햇 9 커널 2.4.20에서는 256개의 한계를 벗어나진 못하는 모양이네요.

일단 결론 부터 말씀드리자면.. 땜방이긴 하겠지만, 레드햇 9에서의 미봉책 정도는 찾은 것 같습니다.

.bash_profile에

export LD_ASSUME_KERNEL=2.2.5

요 한줄을 넣어주면, 메모리 용량에 따라 틀려 질지 몰라도 제 512M 메모리 PC에서는 1500개 정도 까지는 생성이 되더군요.
레드햇 9 쓰시는분 안되셨던분.. 궁금하면 해보시고.. 되시면 글좀 다시 올려주시면 감사하겠고요 ^^

휴.. 이 미봉책은 정말로 쌩쇼를 하다 하다, 어랏.. 이게 머야, 하고.. 정말 우연히(이 말로는 표현이 부족 합니다 T_T) 알아낸 것인데, 현재로서는 커널 컴파일이라던가 다른 방법을 통한 "제대로"된 방법은 알아내지 못했습니다.

환경 변수 하나로 쓰래드의 갯수가 좌우될수 있을줄은 꿈에도 생각 못했습니다. 아직도 머 왜 이렇게 하면 쓰레드 256개의 한계를 넘어설수 있는지는 몰르구요. 혹시 아시는분 설명좀 해주시면 감사하겠고요...

글구 하나 더 발견(?) 한것은.. OS마다 쓰레드가 버주얼 메모리에(스택(?))서 차지하는 쓰레드별 용량이 틀리네요.

레드햇 9의 경우.. 아래와 같이 각 쓰레드는 8메가 정도의 스택(맞나? -_-:)을 먹습니다.
Creating threads ...
Address of c = 1058202 KB
Address of c = 1066394 KB
Address of c = 1074586 KB
Address of c = 1082778 KB
Address of c = 1090970 KB
Address of c = 1099162 KB
Address of c = 1107354 KB
Address of c = 1115546 KB
Address of c = 1123738 KB
Address of c = 1131930 KB
100 threads so far ...
200 threads so far ...

그리고, fibonacci님의 커널 컴팔을 한 데비안의 경우는 아래와 같이 2메가 정도..
Creating threads ...
Address of c = 3137534 KB
Address of c = 3135486 KB
Address of c = 3133438 KB
Address of c = 3131390 KB
Address of c = 3129342 KB
Address of c = 3127294 KB
Address of c = 3125246 KB
Address of c = 3123198 KB
Address of c = 3121150 KB
Address of c = 3119102 KB
100 threads so far ...

다른 분들은 위의 코드부분을 안올려 주셔서 모르겠는데..
아마도 각각 조금씩 틀리지 않을까 합니다. 근데 왜 이렇게 어떤놈은 8메가 씩이나 먹고 어떤넘은 2메가 정도밖에 안먹는지 까지는 제가 아직 모르겠고요..

이런 경우 STACK_SIZE 어쩌고 하는 부분을 수정한후 커널 컴팔을 하면 줄일수 있다던데.. 하고 줏어 들은 바까지는 있습니다.
혹시 이점에 대해 아시는분 글 올려 주시면 감사하겠고요..

어쨋든 급한데로 미봉책은 찾았으니.. 정답을 찾게되면.. 또 글을 올리던지 하겠습니다.

그럼, 테스트 해주신 모둔분들 다시 한번 감사드립니다..

jolasen의 이미지

스텍싸이즈를 줄여 보세요..

Quote:

Linux x.net 2.4.20-13.8smp #1 SMP Mon May 12 11:48:58 EDT 2003 i686 i686 i386 GNU/Linux
[@kiscos test]$ ./thread-limit
스택사이즈:30720
Creating threads ...
Address of c = 1048694 KB
Address of c = 1049066 KB
Address of c = 1049102 KB
Address of c = 1049138 KB
Address of c = 1049174 KB
Address of c = 1049210 KB
Address of c = 1049246 KB
Address of c = 1049282 KB
Address of c = 1049318 KB
Address of c = 1049354 KB
100 threads so far ...
200 threads so far ...
300 threads so far ...
.
.
6700 threads so far ...
6800 threads so far ...
6900 threads so far ...
7000 threads so far ...
7100 threads so far ...
Failed with return code 11 creating thread 7166.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>


#define MAX_THREADS 10000
int i;
size_t sizeofstack;
pthread_attr_t attr;


void run(void) {
  char c;
  if (i < 10)
    printf("Address of c = %u KB\n", (unsigned int) &c / 1024);
  sleep(60 * 60);
}


int main(int argc, char *argv[]) {
  int rc = 0;
  //system("cat /proc/meminfo");
  pthread_t thread[MAX_THREADS];

  pthread_attr_init(&attr);
  
sizeofstack = 1024;
pthread_attr_setstacksize(&attr,sizeofstack*30);

  pthread_attr_getstacksize(&attr,&sizeofstack);
  printf("스택사이즈:%d\n",sizeofstack);

  printf("Creating threads ...\n");
  for (i = 0; i < MAX_THREADS && rc == 0; i++) {
    rc = pthread_create(&(thread[i]), &attr, (void *) &run, NULL);
    if (rc == 0) {
      pthread_detach(thread[i]);
      if ((i + 1) % 100 == 0)
        printf("%i threads so far ...\n", i + 1);
    }
    else {
      //system("cat /proc/meminfo");
      printf("Failed with return code %i creating thread %i.\n",
             rc, i + 1);
        }
  }


  //for (;;) sleep(10);
  exit(0);
}

p.s..늘이는게 아니고 줄이는거네요..죄송

stypr의 이미지

커널 2.4.18-3에서는 스택을 늘려도 소용없군요
255까지 나와요.

FreeBSD 5.1Release에서는 기본으로 문제 없이 10000이상도 나온느군요.

sayung의 이미지

34700 threads so far ...
34800 threads so far ...
34900 threads so far ...
Failed with return code 35 creating thread 34933.

FreeBSD5#
FreeBSD5# uname -a
FreeBSD FreeBSD5.xxx 5.2-CURRENT FreeBSD 5.2-CURRENT #12: Wed Jan 7 02:55:13 KST 2004 root@FreeBSD5.xxx:/usr/obj/usr/src/sys/BSD i386

100000 개로 했더니...
10000 개는 잘됩니다..

866듀얼에 1G 메모리..
그리고 gcc -pthread -o thread-limit th.c
이렇게 컴파일 했습니다.
gcc -lpthread -o thread-limit th.c 이렇게 하니 안되더군요..

FreeBSD5# gcc -lpthread -o thread-limit th.c
/usr/bin/ld: cannot find -lpthread
FreeBSD5#
프비에서는 Address of c = 3002978 KB 가 안나오는군요.
그냥 바로 34700 threads so far ... 이런식으로..

아래는 레드햇 어드밴스 3.0 에서 돌린겁니다.
[root@IDD008 root]# ./thread-limit
Creating threads ...
Address of c = 3002978 KB
Address of c = 2992734 KB
Address of c = 2982490 KB
Address of c = 2972246 KB
Address of c = 2962002 KB
Address of c = 2951758 KB
Address of c = 2941514 KB
Address of c = 2931270 KB
Address of c = 2921026 KB
Address of c = 2910782 KB
100 threads so far ...
200 threads so far ...
300 threads so far ...
Failed with return code 12 creating thread 306.
[root@IDD008 root]#
[root@IDD008 root]#
[root@IDD008 root]# uname -a
Linux IDD008 2.4.21-4.ELsmp #1 SMP Fri Oct 3 17:52:56 EDT 2003 i686 i686 i386 GNU/Linux
[root@IDD008 root]#

550 제온 1메가 cache 4개(쿼드로) 에 4g가에 설치된 리눅스 어드서버 3.0...

프비의 구루가 되기 위해서...

sangwoo의 이미지

sayung wrote:

866듀얼에 1G 메모리..
그리고 gcc -pthread -o thread-limit th.c
이렇게 컴파일 했습니다.
gcc -lpthread -o thread-limit th.c 이렇게 하니 안되더군요..

그냥 참고로..
FreeBSD에는 pthread 라이브러리가 3가지(!!) 있습니다. libc_r (1:N),
libthr (1:1), libkse (M:N) 인데, 5.3-release부터는 현재의 libkse가 libpthread라는
이름으로 설치되고, 기본 pthread 라이브러리가 될 것이라고 합니다.
-pthread 옵션은 4.x대의 일종의 Hack인데 (4.x버전에서는 libc_r과 libc가
동시에 Linking이 되면 동작하지 않기 때문입니다.) 5.x에서는 -lc_r로 변하게
됩니다. 즉,

gcc -lc_r -o thread-limit th.c
gcc -lthr -o thread-limit th.c
gcc -lkse -o thread-limit th.c

등으로 직접 링크하셔도 됩니다.
이것들을 비교해 보는 것도 재미있겠네요.

----
Let's shut up and code.

sisap의 이미지

예.. 스택사이즈를 조정해 줄수 있군요!
그게 제대로된 정답같은데요..

그런데, 기존의 쓰레드는 쓰레드 하나당 8M정도씩 차지하던 것이, 스택 사이즈를 30K정도씩만 차지하도록 함으로써 쓰레드를 많이 생성 시킬수 있도록 하는것 같은데, 스택 사이즈를 늘린다고 표현을 해야 되는건가요?

그리고 만약 그렇게 해서 쓰레드를 생성한다면, 8M정도씩의 공간이 30K로 줄어 들기 때문에 각 쓰레드에서 사용할수 있는 여유 메모리 공간이 줄어 든다고 볼수 있는건가요?

그리고, 제가 뉴스 그룹에도 이 글을 올렸는데 그곳 반응중 하나가, 쓰레드를 그렇게 많이 열면 오히려 비 효율적이다. 라는 답글이 하나 올라 왔던데.. 혹시 그 부분에 대해 좀 설명해 주실수 있는 분이 계신지요.. 뭐에 비해서 비 효율적이라는건지는 얘긴 안해주더만.. 그렇게 쓰레드릴 많이 사용할 바에는 포크시키는게 낫다는 얘긴가?..흠..

이건 게시판 쓰레드(-_-)를 새로 열어서 질문을 올리는게 나을까요?

아 질문에 질문이 꼬리를 무는군요.

오늘 하루도 좋은 하루 되세요~

jolasen의 이미지

줄이는겁니다. 제가 잠시 정신이 나갔었나 봅니다.
단 PTHREAD_STACK_MIN (스택 최소값) 보단 커야할겁니다.
최소값보다 작으면 그냥 기본 값으로 잡혀버리더군요.
그리고 비효율적이란것은 아마도 context switching이야기를
하는거 같네요.

김충길의 이미지

스레드 생성하면서 각 스레드가 모 프로세스의 heap을 다 소모해서 그렇습니다.

이건 예전 리눅스 스레드 버전의 문제 인걸로 아는데 새로 나온(아직 개발 단계인지..)
thread 라이브러리는 어떻게 되는지 모르겠군요.

screen + vim + ctags 좋아요~

cjh의 이미지

RH7.3인가에서 해본 기억은 glibc안에 있는 libpthread부분을 패치해 주어야 했던 걸로 기억합니다.

방법은 윗분이 말씀하신대로 스레드의 스택 크기를 낮추는 것이고요... 8000여개까지 해 보았는데 그때 파일이 어디갔는지 잘 모르겠군요. :<

물론... NPTL같은 다른 스레드 구현은 그런 제한이 없을 겁니다. 차라리 그쪽을 시도해 보시는게...

--
익스펙토 페트로눔

sayung의 이미지

gcc -lc_r -o thread-limit th.c

34600 threads so far ...
34700 threads so far ...
34800 threads so far ...
34900 threads so far ...
Failed with return code 35 creating thread 34933.
FreeBSD5#

gcc -lthr -o thread-limit th.c

FreeBSD5# ./thread-limit
Creating threads ...
Address of c = 3140467 KB
Address of c = 3140603 KB
Address of c = 3140399 KB
Address of c = 3140263 KB
Address of c = 3140195 KB
Address of c = 3140331 KB
Address of c = 3140059 KB
Address of c = 3139991 KB
Address of c = 3140127 KB
100 threads so far ...
Failed with return code 35 creating thread 110.
FreeBSD5#

gcc -lkse -o thread-limit th.c

34600 threads so far ...
34700 threads so far ...
34800 threads so far ...
34900 threads so far ...
Failed with return code 35 creating thread 34933.
FreeBSD5#

이렇게 나오는 군요 ^^;;;

프비의 구루가 되기 위해서...

rainblow의 이미지

위의 소스코드를 참고하여 돌려보았습니다.
Tru-64에서도 stack size를 조절할수가 있더군요.
그런데 한가지 특이한점은,

top 명령어를 통해서 해당 프로세스를 보면 SIZE 항목과 RES 항목이 전혀 줄지가 않더군요.
thread를 12개 생성하도록 했을때..
thread의 stack size를 줄이는 경우와 그렇지 않은 경우에 SIZE항목과 RES항목의 데이터가 변함이 없던데요..

제가 top 명령어의 SIZE 항목에 대한 이해부족인지..

한가지 더 여쭤보면, Unix에서 thread에 대한 정보를 볼수 있는 명령어가 있습니까?

linux는 모르겟지만, 유닉스는 ps -aux 명령어가 옵션이 틀렸다고 나오던데..
solaris 또는 Tru-64 에서 프로세스의 쓰레드 정보를 보는 명령어가 있으면 알려주세요.
감사합니다.

eggboy의 이미지

솔라리스의 경우 /usr/ucb/ps -aux 로 해보시면 될겁니다.

haewoo의 이미지

Sun에서는 pstack 이라는 명령을 이용하여 프로세스의 쓰레드의 상태를 볼수 있습니다.

낙엽의 이미지

sisap wrote:
예.. 스택사이즈를 조정해 줄수 있군요!
그게 제대로된 정답같은데요..

그런데, 기존의 쓰레드는 쓰레드 하나당 8M정도씩 차지하던 것이, 스택 사이즈를 30K정도씩만 차지하도록 함으로써 쓰레드를 많이 생성 시킬수 있도록 하는것 같은데, 스택 사이즈를 늘린다고 표현을 해야 되는건가요?

그리고 만약 그렇게 해서 쓰레드를 생성한다면, 8M정도씩의 공간이 30K로 줄어 들기 때문에 각 쓰레드에서 사용할수 있는 여유 메모리 공간이 줄어 든다고 볼수 있는건가요?

그리고, 제가 뉴스 그룹에도 이 글을 올렸는데 그곳 반응중 하나가, 쓰레드를 그렇게 많이 열면 오히려 비 효율적이다. 라는 답글이 하나 올라 왔던데.. 혹시 그 부분에 대해 좀 설명해 주실수 있는 분이 계신지요.. 뭐에 비해서 비 효율적이라는건지는 얘긴 안해주더만.. 그렇게 쓰레드릴 많이 사용할 바에는 포크시키는게 낫다는 얘긴가?..흠..

이건 게시판 쓰레드(-_-)를 새로 열어서 질문을 올리는게 나을까요?

아 질문에 질문이 꼬리를 무는군요.

오늘 하루도 좋은 하루 되세요~

thread를 많이 열었을 시에는 context switching이 빈번하게 발생하게 되어
적정량을 오픈했을 때 보다 훨씬 부하가 심하게 됩니다.
배보다 배꼽이 더 크다는게 낫겠네요. :-)

FruitsCandy의 이미지

한컴 2.2 (커널 2.4.13-1hl ) 에서는 다음과 같네요.

사양은 아래와 같습니다.
model name : Intel(R) Pentium(R) 4 CPU 1.60GHz
stepping : 4
cpu MHz : 1614.402
cache size : 512 KB
MemTotal: 512628 kB

[Jang_Hancom root]#./thread
Creating threads ...
Address of c = 3137534 KB
Address of c = 3135486 KB
Address of c = 3133438 KB
Address of c = 3131390 KB
Address of c = 3129342 KB
Address of c = 3127294 KB
Address of c = 3125246 KB
Address of c = 3123198 KB
Address of c = 3121150 KB
100 threads so far ...
200 threads so far ...
300 threads so far ...
400 threads so far ...
500 threads so far ...
600 threads so far ...
700 threads so far ...
800 threads so far ...
900 threads so far ...
1000 threads so far ...
Failed with return code 11 creating thread 1022.

2.5메가 정도 잡는것 같네요 ~

아지랑이류 초환상 공콤 화랑... 포기하다.. T.T

권순선의 이미지

fox9 wrote:
예전에 bbs.kldp.org가 생기기 이전의 kldp.org의 게시판에 위와 같은 문제점이 있어서 토론이 오고 간적이 있는데 그때의 게시판을 볼 방법이 없는지. :shock:

그때는 pthread_detatch와 pthread_attr_* 류의 함수등으로 설정해서 한듯 합니다
기억은 안나고... :(


예전 게시판의 글은 모두 현재 이곳에 변환되어 들어와 있으므로 이곳에서 그대로 찾아 보시면 됩니다....
simpid의 이미지

놀랐습니다.
메모리가 허용하는데로 만들 수 있을지 알았습니다. -_-;

그래도 이렇게 조금 만들어 지는지는 몰랐습니다.

Redhat 9.0
CPU : P3 855
RAM : 256M
Failed with return code 12 creating thread 255

Debian 2.4
ThinkPad 560E
CPU : P166 MMX
RAM : 48M
Kernel : Linux version 2.4.18-bf2.4
Failed with return code 11 creating thread 381

재밌는건 사양이 훨씬 떨어지는 노트북에서 좀 더 많은 쓰레드를 만들 수 있는점입니다.
아마도 reahat과 debian의 차이가 아닌가 합니다.

그리고 리턴 코드도 다르군요.

kyong의 이미지

sisap wrote:
안녕하세요?
쓰레드 초보입니다. -_-;;

Pentium 4, 700Mhz, 512M, 리눅스 9.0을 쓰고 있습니다.
커널은 2.4.20-8 이고요..

기존의 fork를 쓰레드로 전환 중인데, fork는 머 한 1000개 정도는 그냥 되는데, 쓰레드는 250 몇개 정도에서 더이상 생성하지를 못하네요.
쓰레드 내부에서는 테스트 하느라고 모두 코멘트 처리를 해 놔서 별 짓 안합니다. 그냥 루프만 돌죠..

255개 정도를 넘어가면서는 pthread_create에서 리턴값이 12가 나와서 뒤져보니 무슨 에러인지/usr/include/asm/errno.h파일에서 뒤져보니
#define ENOMEM 12 /* Out of memory */

요렇게.. Out of memory라고 나오네요.

게시판을 뒤져보며 확인해본 시스템 설정상으로는..
/proc/sys/kernel/threads-max
8191

/usr/include/bits/local_lim.h:
#define PTHREAD_THREADS_MAX 16384

위의 두 값이 왜 틀리게 되어 있는지는 모르겠지만 하여간, Out of memory에러 넘버도 그렇고.. THREADS_MAX값들을 봐서도 메모리 문제 인것같아서 메모리를 체크해 봤습니다.

255개 쓰레드를 생성하고도 메모리는 5메가 정도밖에 안줄더군요.
60메가 정도의 여유 메모리가 있는데, 이건 시스템 전체 메모리니까.. 별 상관은 없을듯하고.. 프로세스당 사용할수있는 메모리 제한에서 걸린 듯 싶어 게시판을 더 뒤져보니..
STACK_SIZE를 조정할수 있다던데..

어떤분은 리눅스 7.x버젼인가에서 pthread_attr_init옵션을 어떻게 줘서 1000개 이상 생성이 되었다고도 하시던데..

저는 오라클 9.1.0이던가? 를 설치 해볼려고 glibc관련 rpm 몇개를 다음과 같은 rpm들로 다운 그레이드 한 상태입니다.
glib-2.3.2-5.i686.rpm glibc-common-2.3.2-5.i386.rpm
glibc-devel-2.3.2-5.i386.rpm

혹시 이것때문에 문제가 있는건 아닌지..

하여간, 조금이라도 도움이 될 수 있는 글이라도 남겨주시면 감사하겠습니다.

참, 모두 새해 복 많이 받이시고요~

추가> 으음.. 이거 계정 환경이 머가 틀린지 pthread_create에서 리턴값이 11이 나오는 계정이 있고 12가 나오는 계정이 있네요..
이건 또 머냐.. 좀 더 디벼 봐야 겠네요..
하여간, 답글 많이좀 달아 주세요 -_-;;

ulimit -u unlimited
하신 후 해 보세요.
지금 딱 거기에 걸리신듯...
그리고 oracle 설치후 glibc 는 다시 업그레이드하셔도 상관없을 듯 합니다.
최소한 같은 버젼에서는 binary호환이 되므로..

에궁..포크도 되고 리턴값을 보니 그게 아니네요..
아뭏든 다른 분들은 참고하시길.

jemiro의 이미지

아래 코드로 디폴트 스택 사이즈를 알수 있습니다.

/*
 * thread_attr.c
 *
 */

#include <limits.h>
#include <pthread.h>

#include "errors.h"

void *thread_routine(void *arg)
{
    printf("The thread is here\n");
 
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_t		thread_id;
    pthread_attr_t	thread_attr;
    size_t		stack_size;
    int			status;
    
    status = pthread_attr_init(&thread_attr);
    if (status != 0)
	err_abort(status, "Create attr");
    
    status = pthread_attr_setdetachstate(&thread_attr,
					 PTHREAD_CREATE_DETACHED);
    if (status != 0)
	err_abort(status, "Set detach");
#ifdef	_POSIX_THREAD_ATTR_STACKSIZE
    status = pthread_attr_getstacksize(&thread_attr, &stack_size);
    if (status != 0)
	err_abort(status, "Get stack size");
    printf("Default stack size is %u: minimum is %u\n",
	   stack_size, PTHREAD_STACK_MIN);
    status = pthread_attr_setstacksize(&thread_attr, PTHREAD_STACK_MIN * 2);
    if (status != 0)
	err_abort(status, "Set stack size");
#endif
    status = pthread_create(&thread_id, &thread_attr, thread_routine, NULL);
    if (status != 0)
	err_abort(status, "Create thread");
    printf("Main exiting\n");
    
    pthread_exit(NULL);
    return 0;
}

테스트 시스템 환경
uname -a
Linux moon 2.6.2 #2 Fri Feb 6 15:04:48 KST 2004 i686 Unknown CPU Type AuthenticAMD GNU/Linux
NPTL패치된 glibc

실행한 결과
Default stack size is 8388608: minimum is 16384
The thread is here
Main exiting

위에서 디폴트 스택사이즈가 큰걸 알수 있습니다.
다시 예제 코드를 좀 수정하여
스택사이즈를 PTHREAD_STACK_MIN * 2로 설정하도록 했습니다.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#include <limits.h>
#include <pthread.h>

#define MAX_THREADS 10000

void *run(void *arg)
{
    char	c;
    if ((int) arg < 10)
	printf("Address of c = %p\n", &c);
    sleep(60);
    
    return NULL;
}

int main(int argc, char *argv[])
{
    pthread_attr_t	thread_attr;
    pthread_t		thread[MAX_THREADS];
    int			status;
    int			i;
    
    status = pthread_attr_init(&thread_attr);
    if (status != 0) {
	perror("pthread_attr_init");
	exit(1);
    }
    status = pthread_attr_setdetachstate(&thread_attr,
					 PTHREAD_CREATE_DETACHED);
    if (status != 0) {
	perror("pthread_attr_setdetachstate");
	exit(1);
    }
    status = pthread_attr_setstacksize(&thread_attr, PTHREAD_STACK_MIN * 2);
    if (status != 0) {
	perror("pthread_attr_setstacksize");
	exit(1);
    }
    
    for (i = 0; i < MAX_THREADS && status == 0; i++) {
	status = pthread_create(&thread[i], &thread_attr, run, (void *) i);
	if (status) {
	    perror("pthread_create");
	    printf("Failed with return code %i creating thread %i.\n",
		   status, i + 1);
	    break;
	}
	if ((i + 1) % 100 == 0)
	    printf("%i threads so far ...\n", i + 1);
    }
    
    pthread_exit(NULL);
    return 0;
}

위에의 코드를 실행하면
9400 threads so far ...
9500 threads so far ...
9600 threads so far ...
9700 threads so far ...
9800 threads so far ...
9900 threads so far ...
10000 threads so far ...

와 같이 깔끔하게 10000개의 쓰레드를 생성할수 있었습니다 :)

kyong의 이미지

애초에 올리신 분은 자체 코드에 메모리 leak였는 것 같네요.
그리고 limit을 테스트하다가....저도 좀 이상해서 redhat에서 리스트를 검색하
다보니, i386 에서는 nptl을 지원 안한다는 것을 알게

익명 사용자의 이미지

아시아눅스 1.0에서 돌려봤는데요.

9300 threads so far ...
9400 threads so far ...
9500 threads so far ...
9600 threads so far ...
9700 threads so far ...
9800 threads so far ...
9900 threads so far ...
10000 threads so far ...
# uname -a
Linux 2.4.21-20.29AXsmp #1 SMP Tue Aug 2 03:59:07 EDT 2005 x86_64 x86_64 x86_64 GNU/Linux

이렇게 나오네요......^^:

익명 사용자의 이미지

둘러보다 흥미로워서 저도 해 봤습니다.
Macbook Air 2011 i5 1.7GHz 10.8.3

$ ./2
Creating threads ...
Address of c = 127679 KB
Address of c = 128203 KB
Address of c = 128727 KB
Address of c = 129251 KB
Address of c = 129775 KB
Address of c = 130299 KB
Address of c = 130823 KB
Address of c = 131347 KB
Address of c = 131871 KB
Address of c = 132395 KB
100 threads so far ...
200 threads so far ...
300 threads so far ...
400 threads so far ...
500 threads so far ...
600 threads so far ...
700 threads so far ...
800 threads so far ...
900 threads so far ...
1000 threads so far ...
1100 threads so far ...
1200 threads so far ...
1300 threads so far ...
1400 threads so far ...
1500 threads so far ...
1600 threads so far ...
1700 threads so far ...
1800 threads so far ...
1900 threads so far ...
2000 threads so far ...
Failed with return code 35 creating thread 2048.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.