12/04/2023

결합 가능한 스레드

발단

C로 다중스레드 프로그래밍을 공부하고 있는데 결합 가능한 스레드 관련 과제 프로그램을 작성하는 도중 마주친 함수에 관해서 간략하게 적어본다. 과제 프로그램은 자연수 N이 입력값으로 들어오면 N부터 1까지 역순으로 숫자를 출력해야 한다. 처음에는 단순하게 배열로 해결하려고 했는데 힌트를 보니 스레드를 하나 생성하고 결합하는 작업을 반복하라고 한다. 즉, N개의 스레드를 생성해서 작업을 진행하는 것이다.


pthread_join()

스레드는 자식 스레드가 종료하고 결합할 때까지 대기해야 하기 때문에 결합 가능한 스레드로 실행되어야 한다. 스레드가 pthread_create() 함수로 생성되면 기본적으로 결합 가능한 스레드로 실행된다. 따라서, 명시적으로 스레드의 속성값을 설정해야 할 필요가 없기에 pthread_attr_t 변수가 필요없다. pthread_join() 함수에서 반환값 부분 때문에 조금 헷갈렸는데 숫자를 출력하고 자식 스레드를 기다리기만 하면 되기 때문에 NULL을 넘기면 된다.
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
 
int N;
 
void *
thr_fn(void *arg) {
  pthread_t next_tid;
  int cnt;
 
  cnt = *(int *)arg;
  free(arg);
 
  if (cnt < N) {
    int err, *next_cnt;
    
    next_cnt = calloc(1sizeof(*next_cnt));
    *next_cnt = cnt + 1;
 
    // 1번 스레드는 2번 스레드를, 2번 스레드는 3번 스레드를, N-1번 스레드는 N번 스레드를 생성한다.
    err = pthread_create(&next_tid, NULL, thr_fn, (void *)next_cnt);
    if (err != 0) {
      printf("오류 발생! 스레드 생성 실패, errno = %d\n", err);
 
      return (void *)-1;
    }
 
    // 2번 스레드는 1번 스레드에, 3번 스레드는 2번 스레드에, ... N번 스레드는 N-1번 스레드에 결합한다.
    err = pthread_join(next_tid, NULL);
    if (err != 0) {
      printf("오류 발생! 스레드 결합 실패, errno = %d\n", err);
 
      return (void *)-2;
    }
  }
 
  printf("%d\n", cnt);
 
  return NULL;
}
 
void
create_thr(pthread_t *tid, int cnt) {
  int err, *_cnt;
  
  _cnt = calloc(1sizeof(*_cnt));
  *_cnt = cnt;
 
  // 1번 스레드를 생성한다.
  err = pthread_create(tid, NULL, thr_fn, (void *)_cnt);
  if (err != 0) {
    printf("오류 발생! 스레드 생성 실패, errno = %d\n", err);
 
    exit(EXIT_FAILURE);    
  }
  
  // 1번 스레드가 메인 스레드에 결합한다.
  err = pthread_join(*tid, NULL);
  if (err != 0) {
    printf("오류 발생! 스레드 결합 실패, errno = %d\n", err);
    
    exit(EXIT_FAILURE);
  }
 
  return;
}
 
int
main(int argc, char *argv[]) {
  pthread_t tid;
  int cnt;
 
  cnt = 1;
  
  scanf("%d"&N);
 
  create_thr(&tid, cnt);
  
  exit(EXIT_SUCCESS);
}
cs

update: 2024.02.14

댓글 없음:

댓글 쓰기