×
Crocus
공부한 내용을 정리하는 블로그로 시작한
Crocus는 2014년 1월 14일 부터 시작하여
현재 월 6만명, 총 2,101,837명의 방문자 수를 기록하고 있습니다.
Donation
이제 많은 사용자들이 이용하는 만큼
더 다양한 서비스 개발/제공을 위해 후원금을 모금하고자 합니다.
후원을 해주시는 분들은 Donators 명단에 성명, 후원금을 기입해드리며
Crocus 블로그가 아닌 다른 곳에 정리해둔 저만의 내용을 공유해 드리고자 합니다.
Account
예금주 : 고관우
신한은행 : 110-334-866541
카카오뱅크 : 3333-01-7888060

👉 후원 페이지 바로가기 Donators
익명 : 5000원(Crocus응원합니다.)
busyhuman: 5000원(유용한 지식 감사합니다.)
익명 : 5000원(알고리즘 학습러)
반응형

- 본 내용은 Linux (Ubuntu 14.04 lts)를 기반으로 제작되었습니다. -


1. Create와 join을 이용한 코드 - 기본


동작 과정 ::


1. threadID라는 스레드 변수를 생성

2. 스레드 생성, 이때 threadID를 인자로 보내어 TID를 받아낸다. 그리고 threadRoutine라는 함수로 스레드를 실행한다.

3. join에 의해 스레드를 기다린다.

4. threadRoutine에서 시작하는 자식 스레드는 TID를 출력한다.

5. 자식 스레드가 종료되고 난 뒤, 메인 스레드는 마지막으로 printf를 출력하고 종료한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Pthread create and join
 
#include <pthread.h>
#include <stdio.h>
 
void *threadRoutine(void *argumentPointer)
{
    pthread_t id = pthread_self();
 
    // TID를 반환하고 출력
    printf("thread ID (TID) :: %lu\n", id);
    
    // 부모 스레드 부분에서 리턴값을 받기때문에 항상 리턴을 해준다.
    return NULL;
}
 
int main()
{
    pthread_t threadID;
    
    // threadID로 TID를 받아오고, threadRoutine라는 함수 포인터로 스레드를 실행한다.
    printf("Create Thread!\n");
    pthread_create(&threadID, NULL, threadRoutine, NULL);
 
    // threadID를 가진 thread가 실행되는 동안 기다린다.
    printf("Main Thread is now waiting for Child Thread!\n");
 
    pthread_join(threadID, NULL);
 
    printf("Main Thread finish waitng Child Thread!\n");
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus









2. Create와 join을 이용한 코드 - argument 넘기기(char형 배열)


동작 과정 ::


1. threadID라는 스레드 변수를 생성

2. 스레드 생성, 이때 threadID를 인자로 보내어 TID를 받아낸다. 그리고 threadRoutine라는 함수로 스레드를 실행한다.

3. (void*)argument를 통해 argument를 스레드가 실행하는 함수에 보낸다. 

4. join에 의해 스레드를 기다린다.

5. argumentPointer로 받은 값을 char *argument가 가리키도록 하고, argumentPointer에서 제대로 값이 왔는지 확인한다.

6. 자식 스레드가 종료되고 난 뒤, 메인 스레드는 마지막으로 printf를 출력하고 종료한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Pthread create and join
 
#include <pthread.h>
#include <stdio.h>
 
void *threadRoutine(void *argumentPointer)
{
    char *argument = (char *)argumentPointer;
 
    printf("%s\n", argument );
    // 부모 스레드 부분에서 리턴값을 받기때문에 항상 리턴을 해준다.
    return NULL;
}
 
int main()
{
    pthread_t threadID;
    
    // threadID로 TID를 받아오고, threadRoutine라는 함수 포인터로 스레드를 실행한다.
    printf("Create Thread!\n");
 
    // 알규먼트를 생성하여 스레드에 보내준다.
    char argument[10= "hello";
 
    pthread_create(&threadID, NULL, threadRoutine, (void*)argument);
 
    // threadID를 가진 thread가 실행되는 동안 기다린다.
    printf("Main Thread is now waiting for Child Thread!\n");
 
    pthread_join(threadID, NULL);
 
    printf("Main Thread finish waitng Child Thread!\n");
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus









3. Create와 join을 이용한 코드 - argument 넘기기(long 형 정수)


동작 과정 ::


1. threadID라는 스레드 변수를 생성

2. 스레드 생성, 이때 threadID를 인자로 보내어 TID를 받아낸다. 그리고 threadRoutine라는 함수로 스레드를 실행한다.

3. (void*)argument를 통해 argument를 스레드가 실행하는 함수에 보낸다. 

4. join에 의해 스레드를 기다린다.

5. argumentPointer로 받은 값을 int argument에 값을 저장하고 + 10을하여 출력한다.

6. 자식 스레드가 종료되고 난 뒤, 메인 스레드는 마지막으로 스레드가 정상적으로 생성 되었었는지 return value를 통해 확인한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Pthread create and join
 
#include <pthread.h>
#include <stdio.h>
 
void *threadRoutine(void *argumentPointer)
{
    long argument;
    argument = *((long *)argumentPointer);
 
    printf("%ld\n", argument + 10 );
    // 부모 스레드 부분에서 리턴값을 받기때문에 항상 리턴을 해준다.
    return NULL;
}
 
int main()
{
    pthread_t threadID;
    
    // threadID로 TID를 받아오고, threadRoutine라는 함수 포인터로 스레드를 실행한다.
    printf("Create Thread!\n");
 
    // 알규먼트를 생성하여 스레드에 보내준다.
    long argument = 1;
    int ret;
    ret = pthread_create(&threadID, NULL, threadRoutine, (void*)&argument);
 
    // threadID를 가진 thread가 실행되는 동안 기다린다.
    printf("Main Thread is now waiting for Child Thread!\n");
 
    pthread_join(threadID, NULL);
 
    printf("Main Thread finish waitng Child Thread!\n");
 
    printf("Return Value (0 : success , others : fail) :: %d\n",ret);
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus




4. Create와 join을 이용한 코드 - 스레드 함수에서의 return


동작 과정 ::


1. threadID라는 스레드 변수를 생성

2. 스레드 생성, 이때 threadID를 인자로 보내어 TID를 받아낸다. 그리고 threadRoutine라는 함수로 스레드를 실행한다.

3. (void*)argument를 통해 argument를 스레드가 실행하는 함수에 보낸다. 

4. join에 의해 스레드를 기다린다.

5. argumentPointer로 받은 값을 int argument에 값을 저장하고 + 10을하여 return한다.

6. 자식 스레드가 종료되고 난 뒤, 메인 스레드는 마지막으로 스레드가 정상적으로 생성 되었었는지 return value를 통해 확인한다.

7. join함수의 2번째 인자인 value에 자식 스레드에서 리턴이 제대로 왔는지 printf를 통해 확인한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Pthread create and join
 
#include <pthread.h>
#include <stdio.h>
 
void *threadRoutine(void *argumentPointer)
{
    long argument;
    argument = *((long *)argumentPointer);
 
    // 부모 스레드 부분에서 리턴값을 받기때문에 항상 리턴을 해준다.
    return (void*)(argument + 10);
}
 
int main()
{
    pthread_t threadID;
    
    // threadID로 TID를 받아오고, threadRoutine라는 함수 포인터로 스레드를 실행한다.
    printf("Create Thread!\n");
 
    // 알규먼트를 생성하여 스레드에 보내준다.
    long argument = 1;
    int ret;
    void *value;
 
    ret = pthread_create(&threadID, NULL, threadRoutine, (void*)&argument);
 
    // threadID를 가진 thread가 실행되는 동안 기다린다.
    printf("Main Thread is now waiting for Child Thread!\n");
 
    pthread_join(threadID, &value);
 
    printf("Main Thread finish waitng Child Thread!\n");
 
    printf(" == Return Value (0 : success , others : fail) :: %d\n",ret);
    printf(" == Receive Value :: %ld\n", (long)value); 
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus




5. Create와 join을 이용한 코드 - 스레드의 Create 및 Detach


동작 과정 ::


1. threadID라는 스레드 변수를 생성

2. 스레드를 생성하려면 아무키나 누르고 엔터를 받는다.

3. 스레드 생성, 이때 threadID를 인자로 보내어 TID를 받아낸다. 그리고 threadRoutine라는 함수로 스레드를 실행한다.

4. 스레드를 detach하려면 아무키나 누르고 엔터를 받는다.

5. detach에 의해 스레드가 독립적으로 움직인다.

6. 처음에는 자식 스레드에서 a만 출력하다가 지금부터는 a와 b를 동시에 출력한다. (컨텍스트 스위칭에 따라)



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Pthread create and detach
 
#include <pthread.h>
#include <stdio.h>
 
void *threadRoutine(void *argumentPointer)
{
    pthread_t id = pthread_self();
 
    // TID를 반환하고 출력
    printf("thread ID (TID) :: %lu\n", id);
    
    while(1)
    {
        printf("a\n");
    }
 
    // 부모 스레드 부분에서 리턴값을 받기때문에 항상 리턴을 해준다.
    return NULL;
}
 
int main()
{
    pthread_t threadID;
    char tmp[10];
 
    // threadID로 TID를 받아오고, threadRoutine라는 함수 포인터로 스레드를 실행한다.
    printf(" == If you want Create Thread, write everything and enter == \n");
    scanf("%s",tmp);
 
    printf(" == Create Thread! ==\n");
    pthread_create(&threadID, NULL, threadRoutine, NULL);
 
    // threadID를 가진 thread를 detach한다.
    printf(" == If you want Detach, write everything and enter == \n");
    scanf("%s",tmp);
 
    pthread_detach(threadID);
 
    printf(" == Complete == \n");
 
    while(1){printf("b\n");}
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus




처음 프로세스 실행 상태와 트리를 보여준다.




자식 스레드가 실행되고 난 뒤, 트리에 threadTest4 뒤에 -{threadTest4}가 생김을 볼 수 있다.




Detach되고 난뒤 장면, b와 a가 컨텍스트 스위칭에 따라 서로 동작하고 있다.




여기서 보면 상태가 futex_ 였다가 wait_w였다가를 반복한다.


futex_에 대해서는 정확한 검색 결과가 나오지는 않지만 


아마 뮤텍스, 세마포어(다음 게시물에 나옵니다.)와 비슷한 내용일 것으로 추정되고,  컨텍스트 스위칭과 연관이 있어보인다.







반응형