pthread_create(3) - wariua/manpages-ko GitHub Wiki

NAME

pthread_create - μƒˆ μŠ€λ ˆλ“œ λ§Œλ“€κΈ°

SYNOPSIS

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg);

-pthread둜 링크.

DESCRIPTION

pthread_create() ν•¨μˆ˜λŠ” 호좜 ν”„λ‘œμ„ΈμŠ€ λ‚΄μ—μ„œ μƒˆ μŠ€λ ˆλ“œλ₯Ό μ‹œμž‘ν•œλ‹€. μƒˆ μŠ€λ ˆλ“œλŠ” start_routine() 호좜둜 싀행을 μ‹œμž‘ν•˜λ©° argκ°€ start_routine()의 μœ μΌν•œ 인자둜 μ „λ‹¬λœλ‹€.

μƒˆ μŠ€λ ˆλ“œλŠ” λ‹€μŒ 쀑 ν•œ λ°©λ²•μœΌλ‘œ μ’…λ£Œν•œλ‹€.

  • pthread_exit(3)을 ν˜ΈμΆœν•œλ‹€. μ§€μ •ν•œ μ’…λ£Œ μƒνƒœ 값을 동일 ν”„λ‘œμ„ΈμŠ€ λ‚΄μ˜ λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ pthread_join(3)을 ν˜ΈμΆœν•΄μ„œ 얻을 수 μžˆλ‹€.

  • start_routine()μ—μ„œ λ°˜ν™˜ν•œλ‹€. return 문에 μ£ΌλŠ” κ°’μœΌλ‘œ pthread_exit(3)을 ν˜ΈμΆœν•˜λŠ” 것과 λ™λ“±ν•˜λ‹€.

  • μ·¨μ†Œλœλ‹€. (pthread_cancel(3) μ°Έκ³ .)

  • ν”„λ‘œμ„ΈμŠ€ λ‚΄μ˜ μ–΄λŠ μŠ€λ ˆλ“œκ°€ exit(3)을 ν˜ΈμΆœν•˜κ±°λ‚˜ 메인 μŠ€λ ˆλ“œκ°€ main()μ—μ„œ λ°˜ν™˜μ„ μˆ˜ν–‰ν•œλ‹€. 그러면 ν”„λ‘œμ„ΈμŠ€ λ‚΄μ˜ λͺ¨λ“  μŠ€λ ˆλ“œλ“€μ΄ μ’…λ£Œν•œλ‹€.

attr μΈμžλŠ” pthread_attr_t ꡬ쑰체λ₯Ό κ°€λ¦¬ν‚€λŠ”λ°, κ·Έ λ‚΄μš©λ¬Όμ„ μŠ€λ ˆλ“œ 생성 μ‹œμ μ— μ‚¬μš©ν•΄μ„œ μƒˆ μŠ€λ ˆλ“œμ˜ 속성을 κ²°μ •ν•œλ‹€. pthread_attr_init(3) 및 κ΄€λ ¨ ν•¨μˆ˜λ“€λ‘œ 이 ꡬ쑰체λ₯Ό μ΄ˆκΈ°ν™” ν•œλ‹€. attr이 NULL이면 κΈ°λ³Έ μ†μ„±μœΌλ‘œ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•œλ‹€.

pthread_create() 호좜이 μ„±κ³΅ν•˜λ©΄ λ°˜ν™˜ 전에 μƒˆ μŠ€λ ˆλ“œμ˜ IDλ₯Ό threadκ°€ κ°€λ¦¬ν‚€λŠ” 버퍼에 μ €μž₯ν•œλ‹€. μ΄ν›„μ˜ λ‹€λ₯Έ pthreads ν•¨μˆ˜ ν˜ΈμΆœμ—μ„œ 이 μ‹λ³„μžλ₯Ό μ‚¬μš©ν•΄ μŠ€λ ˆλ“œλ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

μƒˆ μŠ€λ ˆλ“œλŠ” μƒμ„±μž μŠ€λ ˆλ“œμ˜ μ‹œκ·Έλ„ 마슀크 사본을 λ¬Όλ €λ°›λŠ”λ‹€ (pthread_sigmask(3)). μƒˆ μŠ€λ ˆλ“œμ˜ 미처리 μ‹œκ·Έλ„ 집합은 λΉ„μ–΄ μžˆλ‹€ (sigpending(2)). μƒˆ μŠ€λ ˆλ“œλŠ” μƒμ„±μž μŠ€λ ˆλ“œμ˜ λŒ€μ²΄ μ‹œκ·Έλ„ μŠ€νƒμ„ λ¬Όλ €λ°›μ§€ μ•ŠλŠ”λ‹€ (sigaltstack(2)).

μƒˆ μŠ€λ ˆλ“œλŠ” 호좜 μŠ€λ ˆλ“œμ˜ λΆ€λ™μ†Œμˆ˜μ  ν™˜κ²½μ„ λ¬Όλ €λ°›λŠ”λ‹€ (fenv(3)).

μƒˆ μŠ€λ ˆλ“œμ˜ CPU μ‹œκ°„ 클럭 초기 값은 0이닀 (pthread_getcpuclockid(3)).

λ¦¬λˆ…μŠ€ ν•œμ • μ„ΈλΆ€ 사항

μƒˆ μŠ€λ ˆλ“œλŠ” 호좜 μŠ€λ ˆλ“œμ˜ μ—­λŠ₯ μ§‘ν•©λ“€(capabilities(7))κ³Ό CPU μΉœν™”μ„± 마슀크(sched_setaffinity(2)) 사본을 λ¬Όλ €λ°›λŠ”λ‹€.

RETURN VALUE

성곡 μ‹œ pthread_create()λŠ” 0을 λ°˜ν™˜ν•œλ‹€. 였λ₯˜ μ‹œ 였λ₯˜ 번호λ₯Ό λ°˜ν™˜ν•˜λ©° *thread λ‚΄μš©μ€ κ·œμ •λ˜μ–΄ μžˆμ§€ μ•Šλ‹€.

ERRORS

EAGAIN
μŠ€λ ˆλ“œλ₯Ό μƒˆλ‘œ 생성할 μžμ›μ΄ μΆ©λΆ„ν•˜μ§€ μ•Šλ‹€.
EAGAIN
μ‹œμŠ€ν…œμ΄ μ μš©ν•˜λŠ” μŠ€λ ˆλ“œ 개수 ν•œκ³„μ— λΆ€λ”ͺμ³€λ‹€. 이 였λ₯˜λ₯Ό μΌμœΌν‚¬ 수 μžˆλŠ” μ œν•œλ“€μ΄ μ—¬λŸ¬ κ°€μ§€ μžˆλ‹€. μ‹€μ œ μ‚¬μš©μž ID별 ν”„λ‘œμ„ΈμŠ€ 및 μŠ€λ ˆλ“œ 개수λ₯Ό μ œν•œν•˜λŠ” (setrlimit(2)을 톡해 μ„€μ •ν•œ) RLIMIT_NPROC μ—°μ„± μžμ› μ œν•œμ— λ„λ‹¬ν–ˆκ±°λ‚˜, μ»€λ„μ˜ μ‹œμŠ€ν…œ 전체 ν”„λ‘œμ„ΈμŠ€ 및 μŠ€λ ˆλ“œ 개수 μ œν•œμΈ /proc/sys/kernel/threads-max(proc(5) μ°Έκ³ )에 λ„λ‹¬ν–ˆκ±°λ‚˜, PID μ΅œλŒ€ 개수인 /proc/sys/kernel/pid_max(proc(5))에 λ„λ‹¬ν•œ 것이닀.
EINVAL
attr에 μœ νš¨ν•˜μ§€ μ•Šμ€ μ„€μ •.
EPERM
attr에 μ§€μ •ν•œ μŠ€μΌ€μ€„λ§ μ •μ±…κ³Ό λ§€κ°œλ³€μˆ˜λ₯Ό μ„€μ •ν•  κΆŒν•œμ΄ μ—†λ‹€.

ATTRIBUTES

이 μ ˆμ—μ„œ μ‚¬μš©ν•˜λŠ” μš©μ–΄λ“€μ— λŒ€ν•œ μ„€λͺ…은 attributes(7)λ₯Ό 보라.

μΈν„°νŽ˜μ΄μŠ€ 속성 κ°’
pthread_create() μŠ€λ ˆλ“œ μ•ˆμ „μ„± MT-Safe

CONFORMING TO

POSIX.1-2001, POSIX.1-2008.

NOTES

pthread_create()이 *thread둜 λ°˜ν™˜ν•˜λŠ” μŠ€λ ˆλ“œ ID에 λŒ€ν•œ μΆ”κ°€ λ‚΄μš©μ€ pthread_self(3)λ₯Ό 보라. μ‹€μ‹œκ°„ μŠ€μΌ€μ€„λ§ 정책을 μ‚¬μš© 쀑이지 μ•Šλ‹€λ©΄ pthread_create() 호좜 후에 μ–΄λŠ μŠ€λ ˆλ“œ(호좜자 λ˜λŠ” μƒˆ μŠ€λ ˆλ“œ)κ°€ λ‹€μŒμœΌλ‘œ 싀행될지가 λΆˆν™•μ‹€ν•˜λ‹€.

μŠ€λ ˆλ“œλŠ” ν•©λ₯˜ κ°€λŠ₯μ΄κ±°λ‚˜ 뢄리 μƒνƒœμ΄λ‹€. μŠ€λ ˆλ“œκ°€ ν•©λ₯˜ κ°€λŠ₯이면 λ‹€λ₯Έ μŠ€λ ˆλ“œμ—μ„œ pthread_join(3)을 ν˜ΈμΆœν•΄ κ·Έ μŠ€λ ˆλ“œμ˜ μ’…λ£Œλ₯Ό 기닀리고 μ’…λ£Œ μƒνƒœλ₯Ό κ°€μ Έμ˜¬ 수 μžˆλ‹€. μ’…λ£Œν•œ ν•©λ₯˜ κ°€λŠ₯ μŠ€λ ˆλ“œκ°€ ν•©λ₯˜λ˜κ³  λ‚˜μ„œμ•Ό μŠ€λ ˆλ“œμ˜ λ§ˆμ§€λ§‰ μžμ›λ“€μ΄ μ‹œμŠ€ν…œμœΌλ‘œ ν•΄μ œλœλ‹€. 뢄리 μƒνƒœμΈ μŠ€λ ˆλ“œκ°€ μ’…λ£Œν•  λ•ŒλŠ” κ·Έ μžμ›μ΄ μžλ™μœΌλ‘œ μ‹œμŠ€ν…œμœΌλ‘œ ν•΄μ œλœλ‹€. 그리고 μ’…λ£Œ μƒνƒœλ₯Ό μ–»κΈ° μœ„ν•΄ κ·Έ μŠ€λ ˆλ“œμ™€ ν•©λ₯˜ν•˜λŠ” 것이 λΆˆκ°€λŠ₯ν•˜λ‹€. μ‘μš©μ—μ„œ κ·Έ μ’…λ£Œ μƒνƒœμ— μ‹ κ²½μ“°μ§€ μ•ŠλŠ” 일뢀 데λͺ¬ μŠ€λ ˆλ“œμ—μ„œ μŠ€λ ˆλ“œλ₯Ό λΆ„λ¦¬μ‹œν‚€λŠ” 것이 μœ μš©ν•˜λ‹€. μŠ€λ ˆλ“œλ₯Ό 뢄리 μƒνƒœλ‘œ μƒμ„±ν•˜λ„λ‘ (pthread_attr_setdetachstate(3)둜) attr을 μ„€μ •ν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ 기본적으둜 μƒˆ μŠ€λ ˆλ“œλŠ” ν•©λ₯˜ κ°€λŠ₯ μƒνƒœλ‘œ μƒμ„±λœλ‹€.

NPTL μŠ€λ ˆλ”© κ΅¬ν˜„μ—μ„œ ν”„λ‘œκ·Έλž¨ μ‹œμž‘ μ‹œμ μ— μ—°μ„± μžμ› μ œν•œ RLIMIT_STACK이 "λ¬΄μ œν•œ" μ™Έμ˜ 값을 κ°€μ§€κ³  있으면 κ·Έ 값이 μƒˆ μŠ€λ ˆλ“œμ˜ κΈ°λ³Έ μŠ€νƒ 크기λ₯Ό κ²°μ •ν•œλ‹€. κΈ°λ³Έκ³Ό λ‹€λ₯Έ μŠ€νƒ 크기λ₯Ό μ›ν•œλ‹€λ©΄ μŠ€λ ˆλ“œ 생성에 μ“°λŠ” attr μΈμžμ— pthread_attr_setstacksize(3)으둜 μŠ€νƒ 크기 속성을 λͺ…μ‹œμ μœΌλ‘œ μ„€μ •ν•  수 μžˆλ‹€. RLIMIT_STACK μžμ› μ œν•œμ΄ "λ¬΄μ œν•œ"으둜 섀정돼 있으면 μŠ€νƒ 크기에 μ•„ν‚€ν…μ²˜λ³„ 값을 μ‚¬μš©ν•œλ‹€. λ‹€μŒμ€ λͺ‡λͺ‡ μ•„ν‚€ν…μ²˜μ˜ 값이닀.

μ•„ν‚€ν…μ²˜ κΈ°λ³Έ μŠ€νƒ 크기
i386 2 MB
IA-64 32 MB
PowerPC 4 MB
S/390 2 MB
Sparc-32 2 MB
Sparc-64 4 MB
x86_64 2 MB

BUGS

ꡬ식이 된 LinuxThreads κ΅¬ν˜„μ—μ„œλŠ” ν”„λ‘œμ„ΈμŠ€ λ‚΄μ˜ 각 μŠ€λ ˆλ“œκ°€ μ„œλ‘œ λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€ IDλ₯Ό κ°€μ§„λ‹€. μ΄λŠ” POSIX μŠ€λ ˆλ“œ λͺ…μ„Έ μœ„λ°˜μ΄λ©° λ‹€λ₯Έ μ—¬λŸ¬ ν‘œμ€€ λΉ„μ€€μˆ˜ μ‚¬ν•­λ“€μ˜ μ›μ²œμ΄λ‹€. pthreads(7) μ°Έκ³ .

EXAMPLE

μ•„λž˜ ν”„λ‘œκ·Έλž¨μ€ pthread_create() 및 pthreads API의 λ‹€λ₯Έ μ—¬λŸ¬ ν•¨μˆ˜λ“€μ˜ μ‚¬μš© 방식을 보여 μ€€λ‹€.

NPTL μŠ€λ ˆλ”© κ΅¬ν˜„μ„ μ œκ³΅ν•˜λŠ” μ‹œμŠ€ν…œμ—μ„œμ˜ λ‹€μŒ μ‹€ν–‰μ—μ„œ μŠ€νƒ 크기 기본값은 "μŠ€νƒ 크기" μžμ› μ œν•œμ˜ 값이닀.

$ ulimit -s
8192            # μŠ€νƒ 크기 μ œν•œ 8MB (0x800000λ°”μ΄νŠΈ)
$ ./a.out hola salut servus
Thread 1: top of stack near 0xb7dd03b8; argv_string=hola
Thread 2: top of stack near 0xb75cf3b8; argv_string=salut
Thread 3: top of stack near 0xb6dce3b8; argv_string=servus
Joined with thread 1; returned value was HOLA
Joined with thread 2; returned value was SALUT
Joined with thread 3; returned value was SERVUS

λ‹€μŒ μ‹€ν–‰μ—μ„œλŠ” ν”„λ‘œκ·Έλž¨μ—μ„œ λͺ…μ‹œμ μœΌλ‘œ 생성 μŠ€λ ˆλ“œμ˜ μŠ€νƒ 크기λ₯Ό (pthread_attr_setstacksize(3)둜) 1MB둜 μ„€μ •ν•œλ‹€.

$ ./a.out -s 0x100000 hola salut servus
Thread 1: top of stack near 0xb7d723b8; argv_string=hola
Thread 2: top of stack near 0xb7c713b8; argv_string=salut
Thread 3: top of stack near 0xb7b703b8; argv_string=servus
Joined with thread 1; returned value was HOLA
Joined with thread 2; returned value was SALUT
Joined with thread 3; returned value was SERVUS

ν”„λ‘œκ·Έλž¨ μ†ŒμŠ€

#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>

#define handle_error_en(en, msg) \
        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

#define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)

struct thread_info {    /* thread_start() 인자둜 μ‚¬μš© */
    pthread_t thread_id;        /* pthread_create()이 λ°˜ν™˜ν•˜λŠ” ID */
    int       thread_num;       /* μ‘μš©μ—μ„œ μ •μ˜ν•œ μŠ€λ ˆλ“œ 번호 */
    char     *argv_string;      /* λͺ…λ Ήν–‰ μΈμžμ—μ„œ 온 κ°’ */
};

/* μŠ€λ ˆλ“œ μ‹œμž‘ ν•¨μˆ˜: μŠ€νƒ 상단 근처의 μ£Όμ†Œλ₯Ό ν‘œμ‹œν•˜κ³ 
   argv_string을 λŒ€λ¬Έμžλ‘œ λ°”κΎΌ 사본을 λ°˜ν™˜ */

static void *
thread_start(void *arg)
{
    struct thread_info *tinfo = arg;
    char *uargv, *p;

    printf("Thread %d: top of stack near %p; argv_string=%s\n",
            tinfo->thread_num, &p, tinfo->argv_string);

    uargv = strdup(tinfo->argv_string);
    if (uargv == NULL)
        handle_error("strdup");

    for (p = uargv; *p != '\0'; p++)
        *p = toupper(*p);

    return uargv;
}

int
main(int argc, char *argv[])
{
    int s, tnum, opt, num_threads;
    struct thread_info *tinfo;
    pthread_attr_t attr;
    int stack_size;
    void *res;

    /* "-s" μ˜΅μ…˜μ€ μŠ€λ ˆλ“œμ˜ μŠ€νƒ 크기λ₯Ό λ‚˜νƒ€λƒ„ */

    stack_size = -1;
    while ((opt = getopt(argc, argv, "s:")) != -1) {
        switch (opt) {
        case 's':
            stack_size = strtoul(optarg, NULL, 0);
            break;

        default:
            fprintf(stderr, "Usage: %s [-s stack-size] arg...\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    num_threads = argc - optind;

    /* μŠ€λ ˆλ“œ 생성 속성 μ΄ˆκΈ°ν™” */

    s = pthread_attr_init(&attr);
    if (s != 0)
        handle_error_en(s, "pthread_attr_init");

    if (stack_size > 0) {
        s = pthread_attr_setstacksize(&attr, stack_size);
        if (s != 0)
            handle_error_en(s, "pthread_attr_setstacksize");
    }

    /* pthread_create() 인자λ₯Ό μœ„ν•œ λ©”λͺ¨λ¦¬ ν• λ‹Ή */

    tinfo = calloc(num_threads, sizeof(struct thread_info));
    if (tinfo == NULL)
        handle_error("calloc");

    /* λͺ…λ Ήν–‰ μΈμžλ§ˆλ‹€ ν•˜λ‚˜μ”© μŠ€λ ˆλ“œ 생성 */

    for (tnum = 0; tnum < num_threads; tnum++) {
        tinfo[tnum].thread_num = tnum + 1;
        tinfo[tnum].argv_string = argv[optind + tnum];

        /* pthread_create() 호좜이 tinfo[]의 ν•΄λ‹Ή ν•­λͺ©μ—
           μŠ€λ ˆλ“œ IDλ₯Ό μ €μž₯함 */

        s = pthread_create(&tinfo[tnum].thread_id, &attr,
                           &thread_start, &tinfo[tnum]);
        if (s != 0)
            handle_error_en(s, "pthread_create");
    }

    /* λ”λŠ” ν•„μš”μΉ˜ μ•ŠμœΌλ―€λ‘œ μŠ€λ ˆλ“œ 속성 객체 파기 */

    s = pthread_attr_destroy(&attr);
    if (s != 0)
        handle_error_en(s, "pthread_attr_destroy");

    /* 이제 각 μŠ€λ ˆλ“œμ™€ ν•©λ₯˜ν•˜κ³  λ°˜ν™˜ 값을 ν‘œμ‹œ */

    for (tnum = 0; tnum < num_threads; tnum++) {
        s = pthread_join(tinfo[tnum].thread_id, &res);
        if (s != 0)
            handle_error_en(s, "pthread_join");

        printf("Joined with thread %d; returned value was %s\n",
                tinfo[tnum].thread_num, (char *) res);
        free(res);      /* μŠ€λ ˆλ“œκ°€ ν• λ‹Ήν•œ λ©”λͺ¨λ¦¬ ν•΄μ œ */
    }

    free(tinfo);
    exit(EXIT_SUCCESS);
}

SEE ALSO

getrlimit(2), pthread_attr_init(3), pthread_cancel(3), pthread_detach(3), pthread_equal(3), pthread_exit(3), pthread_getattr_np(3), pthread_join(3), pthread_self(3), pthread_setattr_default_np(3), pthreads(7)


2018-04-30

⚠️ **GitHub.com Fallback** ⚠️