pthread_join()에 문제가....

dibira9의 이미지



	for(i=0; i<10000; i++) {

		if ((error = pthread_create(wrt_thread + i, NULL, (void *)process_fd, my_arg))) {
			fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
			wrt_thread[i] = pthread_self();

//여기서 쓰레드가 'Cannot allocate memory' 에러로 인해 더이상 생성 되지 않을 때, (제 리눅스에선 MAX가 255개)
//기존의 쓰레드가 완료 될 때까지 기다리게 했습니다.


			for (j=0; j<i; j++) {
				if (pthread_equal(pthread_self(), wrt_thread[j]))
					continue;
				if ((error = pthread_join(wrt_thread[j], NULL))) {
					fprintf(stderr, "[%d] Failed to join thread: %s\n", j, strerror(error));
					switch(error) {
						case EINVAL:
			//				fprintf(stderr, "1\n");
							break;
						case ESRCH:
			//				fprintf(stderr, "2\n");
							break;
					}
				} else { fprintf(stderr, "!!!\n"); }

				fprintf(stderr, "in %d\n", j);
			}
		}

	}

근데 자꾸 시그먼트폴트 에러가 나는 군요..

GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) run
(생략)
.
.
.
.

[Thread 1980966848 (LWP 26465) exited]
[Thread 1989355328 (LWP 26466) exited]
[Thread 1997743808 (LWP 26467) exited]
[Thread 2006132288 (LWP 26468) exited]
[Thread 2014520768 (LWP 26469) exited]
[Thread 2022909248 (LWP 26470) exited]
[Thread 2031297728 (LWP 26471) exited]
[Thread 2039686208 (LWP 26472) exited]
[Thread 2048074688 (LWP 26473) exited]
[Thread 2056463168 (LWP 26474) exited]
[Thread 2064851648 (LWP 26475) exited]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1074090624 (LWP 26350)]
0x4002fe67 in pthread_join () from /lib/tls/libpthread.so.0
(gdb) bt
#0 0x4002fe67 in pthread_join () from /lib/tls/libpthread.so.0
#1 0x080498d9 in main (argc=1, argv=0xbffff9b4) at mo_test.c:461
(gdb) quit

참고로 쓰레드 하나당 join을 붙였을 땐 잘 돌아갑니다. 그치만 하나당 join을 붙여버리면 쓰레드 사용할 이유가 없는것 같군요...

pthread_join에 문제가 있는것 같은데 제 커널 버전은

"Linux develop 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux"
입니다.

누가 아시는 것 있음, 말씀 좀 부탁드립니다.

PS - goto문으로 돌리거나 sleep 주는 방법 말구요.. (ㅡ,.ㅡ;;)

hanzo69의 이미지

         

// 요 아래에서 process_fd에 뭘 넣으셨는지 궁금하네요. 
// 쓰레드 프로시져의 주소(함수포인터)가 들어가야 합니다만.. fd라...
if ((error = pthread_create(wrt_thread + i, NULL, (void *)process_fd, my_arg))) { // 실패했을 경우

// 요 아래의 pthread_self() 는 항상 같은 값을 반환합니다.
// main()을 호출하고 이 코드를 실행하는 쓰레드죠.
// posix thread 는 fork()처럼 현재 코드상의 분기를 하는 방식이 아니라
// 함수포인터로 지정된 함수를 호출시키고, 지정된 함수가 return하면 
// 쓰레드가 종료되는 방식입니다.
wrt_thread[i] = pthread_self(); 

for (j=0; j<i; j++) { 
// 이 아래의 pthread_equal은 항상 두 값이 같다고 알려줍니다.
// 배열 내엔 모두 main 쓰레드 id가 들어있으니까요.
  if (pthread_equal(pthread_self(), wrt_thread[j])) 
    continue; 
// 어떻게 돌아갔는지는 모르겠지만 요 아래의 pthread_join은
// 자기 자신을 기다리게 됩니다. wrt_thread[] 의 값들을 조사해보세요.
    if ((error = pthread_join(wrt_thread[j], NULL))) { 
      switch(error) { 
        case EINVAL: 
          break; 
        case ESRCH: 
          break; 
      } 
    } else { fprintf(stderr, "!!!\n"); } 
} // for
} // if

각각의 쓰레드는 위의 코드를 실행하는게 아니라 process_fd로 지정된 주소의 함수를 실행하게 됩니다.
쓰레드 생성이 실패하게 되면.. 실패한 쓰레드 자체가 생성되지 못하므로 다른 쓰레드를 대기한다는 것 자체가 불가능합니다.

님ㅎ 즐~

dibira9의 이미지

우선 답변 감사드리구요..
좀 더 간단히 코딩 했는데... 그래도 pthread_join에서 시그먼트 에러가 나네요...

	pthread_t wrt_thread[500];

	for(i=0; i<100; i++) {
	
		if ((error = pthread_create(&wrt_thread[i], NULL, (void *)process_fd, my_arg))) { //process_fd는 걍 함수...
			fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
			goto main_exit;
		}
	}

//쓰레드 생성을 끝 마쳤습니다. 각 쓰레드는 하나당 5초의 시간 지연이 있어요...

//그리고 기다립니다. 쓰레드 다 끝날때까지..
	for(i=0; i<100; i++) {
		if ((error = pthread_join(wrt_thread[i], NULL))) {
			fprintf(stderr, "Failed to join thread: %s\n", strerror(error));
		} 
		else { fprintf(stderr, "!!!\n"); } 
	}

이유를 도무지 모르겠어요..

쓰레드 쪼인...

다시 물 속으로 들어간 인간.

hanzo69의 이미지

실제 생성된 쓰레드 카운트만큼 하시는게 어떨까 합니다.
아마 100개가 생성이 안되어서 그런 듯 하네요.
그래서 초기화되지 않은 wrt_thread[i] 에 대하여 join을 해서요.

님ㅎ 즐~

dibira9의 이미지

typedef struct _tmp_thread_rec {
int flag;
pthread_t ipd;
struct _tmp_thread_rec * next;
} tmp_thread_rec;

쓰레드 상태 관리하는 큐하나 만들어서
시작하는 놈 플래그 1, 끝나는 놈은 0 일케 해서

끝난놈은 끝난거고,... 플래그 1만 가지는 쓰레드 ipd값으로 쪼인 했더니 쪼인 잘 됩니다.

글고 문제가 ㅤㄷㅚㅆ던게 쪼인도 쪼인이지만 생성할 때 pthread 맥스값이 255 넘어가면서 값이 꼬이더군요..

예로 MAX가 5라 치면
1, 2, 3, 4, 5, 6(에러발생),
1, 2, 3, 4, 5 중 끝나는 놈 기달림
기다리다가 끝난 놈 thread값을 가져가야 할 텐데 끝나지도 않은
5의 값을 가져감...

그래서 생성 thread값을 덤프시켜 보니
1,2,3,4,5,5,4,3,2,1 일케 가더라구요...
그니까 쪼인도 안되고...

아후 저 이것 땜시 2주동안 슬럼프에다 오만 우울증까지 겹쳐서리..
아 오늘 발 뻗고 자겠심... ^^

그려서 따로이 pthread id를 관리하는 배열을 만들어 활용하심이 좋으실듯...

tmp_thread_rec * thread_q; (큐를 만들고)

	
	for(i=0; i<10000; i++) {
	
retry: // 255가 MAX니까 255에서 에러 발생...
		if ((error = pthread_create(&wrt_thread[i], NULL, (void *)process_fd, my_arg))) {
			fprintf(stderr, "[%d] Failed to create thread: %s\n", i, strerror(error));
			//기다림...
			while (thread_q->next) {
				if (thread_q->flag == 1) {

					if (pthread_join (thread_q->ipd, NULL) != 0)
			              fprintf (stderr, "pthread_join");
  				}

				thread_q = thread_q->next;
			}

			goto retry;
		}
	}

// 마지막으로 남아있는 쓰레드 기다림

	while (thread_q->next) {
		if (thread_q->flag == 1) {
			if (pthread_join (thread_q->ipd, NULL) != 0)
				  fprintf (stderr, "pthread_join");
		}

		thread_q = thread_q->next;
	}

해결 코드..

다시 물 속으로 들어간 인간.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.