pthread 에서 pthread_join 이후 pthread_t 값

dehac의 이미지

두번째 소스코드에서 p_thread[0] 값이 NULL 이 되는 이유를 모르겠네요.
혹시 아시나요?

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
 
void *t_function(void *data) {
        int id;
        int i=0;
        id = *((int *)data);
 
        while(1){
                printf("%d : %d\n", id, i);
                i++;
                sleep(1);
 
                if(i == 5) break;
        }
 
        return (void *)i;
}
 
int main() {
        pthread_t p_thread[3];
        int thr_id;
        int status[3];
        int a=1;
        int b=2;
        int c=3;
 
        thr_id = pthread_create(&p_thread[0], NULL, t_function, (void *)&a);
        if(thr_id < 0) {
                perror("thread create error:");
                exit(0);
        }
        thr_id = pthread_create(&p_thread[1], NULL, t_function, (void *)&b);
        if(thr_id < 0) {
                perror("thread create error:");
                exit(0);
        }
        thr_id = pthread_create(&p_thread[2], NULL, t_function, (void *)&c);
        if(thr_id < 0) {
                perror("thread create error:");
                exit(0);
        }
 
        printf("%d/%d/%d\n", p_thread[0], p_thread[1], p_thread[2]);
 
        pthread_join(p_thread[0], (void **)&status[0]);
        if(p_thread[0] == NULL) printf("NULL : ");
        printf("%d : %d\n", p_thread[0], status[0]);
 
        pthread_join(p_thread[1], (void **)&status[1]);
        if(p_thread[1] == NULL) printf("NULL : ");
        printf("%d : %d\n", p_thread[1], status[1]);
 
        pthread_join(p_thread[2], (void **)&status[2]);
        if(p_thread[2] == NULL) printf("NULL : ");
        printf("%d : %d\n", p_thread[2], status[2]);
 
        return 0;
}

결과:
1116952896/1127442752/1137932608
1 : 0
2 : 0
3 : 0
1 : 1
2 : 1
3 : 1
1 : 2
2 : 2
3 : 2
1 : 3
2 : 3
3 : 3
1 : 4
2 : 4
3 : 4
1116952896 : 5
1127442752 : 5
1137932608 : 5

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
 
void *t_function(void *data) {
        int id;
        int i=0;
        id = *((int *)data);
 
        while(1){
                printf("%d : %d\n", id, i);
                i++;
                sleep(1);
 
                if(i == 5) break;
        }
 
        return (void *)i;
}
 
int main() {
        pthread_t p_thread[3];
        int thr_id;
        int status0=0;
        int status1=0;
        int status2=0;
        int a=1;
        int b=2;
        int c=3;
 
        thr_id = pthread_create(&p_thread[0], NULL, t_function, (void *)&a);
        if(thr_id < 0) {
                perror("thread create error:");
                exit(0);
        }
 
        thr_id = pthread_create(&p_thread[1], NULL, t_function, (void *)&b);
        if(thr_id < 0) {
                perror("thread create error:");
                exit(0);
        }
        thr_id = pthread_create(&p_thread[2], NULL, t_function, (void *)&c);
        if(thr_id < 0) {
                perror("thread create error:");
                exit(0);
        }
 
        printf("%d/%d/%d\n", p_thread[0], p_thread[1], p_thread[2]);
 
        pthread_join(p_thread[0], (void **)&status0);
        if(p_thread[0] == NULL) printf("NULL : ");
        printf("%d : %d\n", p_thread[0], status0);
 
        pthread_join(p_thread[1], (void **)&status1);
        if(p_thread[1] == NULL) printf("NULL : ");
        printf("%d : %d\n", p_thread[1], status1);
 
        pthread_join(p_thread[2], (void **)&status2);
        if(p_thread[2] == NULL) printf("NULL : ");
        printf("%d : %d\n", p_thread[2], status2);
 
        return 0;
}

결과:
1100933440/1111423296/1121913152
1 : 0
2 : 0
3 : 0
1 : 1
2 : 1
3 : 1
1 : 2
2 : 2
3 : 2
1 : 3
2 : 3
3 : 3
1 : 4
2 : 4
3 : 4
NULL : 0 : 5
1111423296 : 5
1121913152 : 5

chanik의 이미지

아마도 64-bit Linux에서 테스트중이실 것 같은데요.
64-bit OS에서는 포인터가 8-byte를 차지하므로 pthread_join(pthread_t pid, (void **)&status); 호출하실때
두 번째 인자인 status는 4-byte 타입인 int 말고 long long같은 8-byte 타입으로 정의하셔야 합니다.

4-byte 공간의 포인터를 넘겨주었는데 pthread_join() 내부에서는 8-byte를 덮어쓰기 때문에 생기는 현상입니다.
첫번째 샘플도 같은 문제를 안고있는데 실행경로상 우연히 런타임 오류를 피해가고 있을 뿐입니다.
첫 샘플에서도 매 join 시마다 아래와 같이 status 배열 모두를 인쇄하도록 해 보시면 부작용이 보일 것입니다.

printf("%d : %d\n", p_thread[0], status[0]);
printf("%d : %d\n", p_thread[1], status[1]);
printf("%d : %d\n", p_thread[2], status[2]);

dehac의 이미지

명쾌한 답변 감사합니다.
64bit OS 맞습니다.
long으로 바꾸니 문제없이 동작합니다. ^^