C에서 C11 스레드 라이브러리 사용
이 기사에서는 C에서 C11 스레드 라이브러리를 사용하는 방법에 대한 몇 가지 방법을 설명합니다.
thrd_create
함수를 사용하여 새 스레드를 만들고 주어진 루틴을 C에서 실행합니다
스레딩 지원은 표준 C 언어 사양에서 오랫동안 지연되었으며 마침내 C11에서 실현되었습니다. 그 전에는 POSIX 스레드 API가 다중 스레드 프로그래밍을 활용하는 기본 도구로 사용되었습니다. C11은 플랫폼 의존성없이 사용할 수있는보다 표준적인 인터페이스를 제공했기 때문에 POSIX 버전보다 ISO 언어 API를 사용하는 것이 좋습니다. 두 API는 함수 프로토 타입에서 일치하지 않지만 주요 기능은 대부분 유사합니다. 다음 예제에서는 4 개의 스레드가printHello
함수를 실행하기 시작한 다음 메인 스레드를 결합하지 않고 종료되는 간단한 시나리오를 보여줍니다.
thrd_create
는 세 개의 인수를 취합니다.
- 첫 번째는 스레드 식별자에 대한 포인터입니다.
- 두 번째 인수는 유형-
thrd_start_t
이며 함수 포인터 프로토 타입에 대한typedef
입니다. - 세 번째 매개 변수는 함수에 전달할 수있는 인수를 지정합니다.
thrd_create
의 리턴 상태 코드는enum
값 :thrd_success
,thrd_nomem
및thrd_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_join
은pthread_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
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