C에서 C11 스레드 라이브러리 사용

Jinku Hu 2023년10월12일
  1. thrd_create함수를 사용하여 새 스레드를 만들고 주어진 루틴을 C에서 실행합니다
  2. thrd_join함수를 사용하여 C에서 주어진 스레드를 기다립니다
C에서 C11 스레드 라이브러리 사용

이 기사에서는 C에서 C11 스레드 라이브러리를 사용하는 방법에 대한 몇 가지 방법을 설명합니다.

thrd_create함수를 사용하여 새 스레드를 만들고 주어진 루틴을 C에서 실행합니다

스레딩 지원은 표준 C 언어 사양에서 오랫동안 지연되었으며 마침내 C11에서 실현되었습니다. 그 전에는 POSIX 스레드 API가 다중 스레드 프로그래밍을 활용하는 기본 도구로 사용되었습니다. C11은 플랫폼 의존성없이 사용할 수있는보다 표준적인 인터페이스를 제공했기 때문에 POSIX 버전보다 ISO 언어 API를 사용하는 것이 좋습니다. 두 API는 함수 프로토 타입에서 일치하지 않지만 주요 기능은 대부분 유사합니다. 다음 예제에서는 4 개의 스레드가printHello함수를 실행하기 시작한 다음 메인 스레드를 결합하지 않고 종료되는 간단한 시나리오를 보여줍니다.

thrd_create는 세 개의 인수를 취합니다.

  1. 첫 번째는 스레드 식별자에 대한 포인터입니다.
  2. 두 번째 인수는 유형-thrd_start_t이며 함수 포인터 프로토 타입에 대한typedef입니다.
  3. 세 번째 매개 변수는 함수에 전달할 수있는 인수를 지정합니다.

thrd_create의 리턴 상태 코드는enum값 :thrd_success,thrd_nomemthrd_error를 사용하여 정의됩니다.

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

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

void *printHello(void *thr_id) {
  long tid;
  tid = (long)thr_id;
  printf("Hello There! thread #%ld, pthread ID - %lu\n", tid, thrd_current());
  thrd_exit(EXIT_SUCCESS);
}

int main(int argc, char const *argv[]) {
  thrd_t threads[NUM_THREADS];
  int rc;
  long t;

  for (t = 0; t < NUM_THREADS; t++) {
    rc = thrd_create(&threads[t], (thrd_start_t)printHello, (void *)t);
    if (rc == thrd_error) {
      printf("ERORR; thrd_create() call failed\n");
      exit(EXIT_FAILURE);
    }
  }
  thrd_exit(EXIT_SUCCESS);
}

출력:

Hello There! thread 0, pthread ID - 140215498864384
Hello There! thread 1, pthread ID - 140215490471680
Hello There! thread 3, pthread ID - 140215473686272
Hello There! thread 2, pthread ID - 140215482078976

thrd_join함수를 사용하여 C에서 주어진 스레드를 기다립니다

thrd_joinpthread_join 함수와 유사하며 주어진 스레드가 실행을 마칠 때까지 현재 스레드를 차단합니다. 사용자가 유효한 주소를 제공하는 경우 선택적으로 반환 상태 코드를 저장할 수있는 위치를 나타내는 스레드 식별자와int 포인터의 두 가지 인수가 필요합니다. 이미 분리되거나 결합 된 스레드에서thrd_join이 호출되면 결과는 정의되지 않은 동작입니다. 이 함수는thrd_success 또는thrd_error에 해당하는 값을 반환합니다.

다음 예제 코드는 4 개의 스레드가atomic_int유형 변수를 증가시키는 시나리오를 구현합니다. 마지막으로 다른 사람이 완료 될 때까지 기다리는 메인 스레드는counter의 최종 합계 값을 인쇄합니다.

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

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

atomic_int counter = 0;

enum { MAX_ITER = 1000 };

void *printHello(void *thr_id) {
  long tid;
  tid = (long)thr_id;
  printf("thread %ld started incrementing ID - %lu\n", tid, thrd_current());

  for (int i = 0; i < MAX_ITER; ++i) {
    counter += 1;
  }

  return NULL;
}

int main(int argc, char const *argv[]) {
  thrd_t threads[NUM_THREADS];
  int rc;
  long t;

  for (t = 0; t < NUM_THREADS; t++) {
    rc = thrd_create(&threads[t], (thrd_start_t)printHello, (void *)t);
    if (rc == thrd_error) {
      printf("ERORR; thrd_create() call failed\n");
      exit(EXIT_FAILURE);
    }
  }

  for (t = 0; t < NUM_THREADS; t++) {
    thrd_join(threads[t], NULL);
  }
  printf("count = %d\n", counter);

  thrd_exit(EXIT_SUCCESS);
}

출력:

thread 0 started incrementing ID - 139729818216192
thread 2 started incrementing ID - 139729801430784
thread 3 started incrementing ID - 139729793038080
thread 1 started incrementing ID - 139729809823488
count = 4000
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

관련 문장 - C Thread