C Language
스레드 (기본)
수색…
통사론
-
#ifndef __STDC_NO_THREADS__
-
# include <threads.h>
-
#endif
-
void call_once(once_flag *flag, void (*func)(void));
-
int cnd_broadcast(cnd_t *cond);
-
void cnd_destroy(cnd_t *cond);
-
int cnd_init(cnd_t *cond);
-
int cnd_signal(cnd_t *cond);
-
int cnd_timedwait(cnd_t *restrict cond, mtx_t *restrict mtx, const struct timespec *restrict ts);
-
int cnd_wait(cnd_t *cond, mtx_t *mtx);
-
void mtx_destroy(mtx_t *mtx);
-
int mtx_init(mtx_t *mtx, int type);
-
int mtx_lock(mtx_t *mtx);
-
int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts);
-
int mtx_trylock(mtx_t *mtx);
-
int mtx_unlock(mtx_t *mtx);
-
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
-
thrd_t thrd_current(void);
-
int thrd_detach(thrd_t thr);
-
int thrd_equal(thrd_t thr0, thrd_t thr1);
-
_Noreturn void thrd_exit(int res);
-
int thrd_join(thrd_t thr, int *res);
-
int thrd_sleep(const struct timespec *duration, struct timespec* remaining);
-
void thrd_yield(void);
-
int tss_create(tss_t *key, tss_dtor_t dtor);
-
void tss_delete(tss_t key);
-
void *tss_get(tss_t key);
-
int tss_set(tss_t key, void *val);
비고
C11 스레드는 선택적 기능입니다. 그들의 부재는 __STDC__NO_THREAD__
로 테스트 할 수 있습니다. 현재 (2016 년 7 월)이 기능은 C11을 지원하는 모든 C 라이브러리에서 아직 구현되지 않았습니다.
C11 스레드를 지원하는 것으로 알려진 C 라이브러리는 다음과 같습니다.
C11 스레드를 지원하지 않는 C 라이브러리 :
여러 스레드 시작
#include <stdio.h>
#include <threads.h>
#include <stdlib.h>
struct my_thread_data {
double factor;
};
int my_thread_func(void* a) {
struct my_thread_data* d = a;
// do something with d
printf("we found %g\n", d->factor);
// return an success or error code
return d->factor > 1.0;
}
int main(int argc, char* argv[argc+1]) {
unsigned n = 4;
if (argc > 1) n = strtoull(argv[1], 0, 0);
// reserve space for the arguments for the threads
struct my_thread_data D[n]; // can't be initialized
for (unsigned i = 0; i < n; ++i) {
D[i] = (struct my_thread_data){ .factor = 0.5*i, };
}
// reserve space for the ID's of the threads
thrd_t id[4];
// launch the threads
for (unsigned i = 0; i < n; ++i) {
thrd_create(&id[i], my_thread_func, &D[i]);
}
// Wait that all threads have finished, but throw away their
// return values
for (unsigned i = 0; i < n; ++i) {
thrd_join(id[i], 0);
}
return EXIT_SUCCESS;
}
하나의 스레드에 의한 초기화
대부분의 경우, 여러 스레드가 액세스하는 모든 데이터는 스레드가 작성되기 전에 초기화되어야합니다. 이렇게하면 모든 스레드가 클리어 상태로 시작하고 경쟁 조건 이 발생하지 않습니다.
이것이 가능하지 않으면 once_flag
및 call_once
사용할 수 있습니다.
#include <threads.h>
#include <stdlib.h>
// the user data for this example
double const* Big = 0;
// the flag to protect big, must be global and/or static
static once_flag onceBig = ONCE_INIT;
void destroyBig(void) {
free((void*)Big);
}
void initBig(void) {
// assign to temporary with no const qualification
double* b = malloc(largeNum);
if (!b) {
perror("allocation failed for Big");
exit(EXIT_FAILURE);
}
// now initialize and store Big
initializeBigWithSophisticatedValues(largeNum, b);
Big = b;
// ensure that the space is freed on exit or quick_exit
atexit(destroyBig);
at_quick_exit(destroyBig);
}
// the user thread function that relies on Big
int myThreadFunc(void* a) {
call_once(&onceBig, initBig);
// only use Big from here on
...
return 0;
}
once_flag
는 동일한 데이터 Big
을 초기화하려는 다른 스레드를 조정하는 데 사용됩니다. call_once
호출하면
-
initBig
는 정확히 한 번 호출됩니다. -
call_once
대한 호출이 동일하거나 다른 스레드에 의해 이루어질 때까지initBig
.
할당 이외에도, 이러한 회라는 함수 할 일반적인 것은 같은 스레드 제어 데이터 구조의 동적 초기화이다 mtx_t
또는 cnd_t
그하여 정적으로 초기화 할 수 mtx_init
또는 cnd_init
각각.
Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow