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

NAME

pthread_cleanup_push, pthread_cleanup_pop - ์Šค๋ ˆ๋“œ ์ทจ์†Œ ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ ์ง‘์–ด๋„ฃ๊ธฐ์™€ ๊บผ๋‚ด๊ธฐ

SYNOPSIS

#include <pthread.h>

void pthread_cleanup_push(void (*routine)(void *),
                          void *arg);
void pthread_cleanup_pop(int execute);

-pthread๋กœ ๋งํฌ.

DESCRIPTION

์ด ํ•จ์ˆ˜๋“ค์€ ํ˜ธ์ถœ ์Šค๋ ˆ๋“œ์˜ ์Šค๋ ˆ๋“œ ์ทจ์†Œ ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ ์Šคํƒ์„ ์กฐ์ž‘ํ•œ๋‹ค. ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ทจ์†Œ๋  ๋•Œ (๋˜๋Š” ์•„๋ž˜์—์„œ ์„ค๋ช…ํ•˜๋Š” ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—) ์ž๋™์œผ๋กœ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ•ธ๋“ค๋Ÿฌ์—์„œ ๋ฎคํ…์Šค๋ฅผ ๋†“์•„์„œ ํ”„๋กœ์„ธ์Šค ๋‚ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋“ค์—๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

pthread_cleanup_push() ํ•จ์ˆ˜๋Š” ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ ์Šคํƒ ์ƒ๋‹จ์— routine์„ ์ง‘์–ด๋„ฃ๋Š”๋‹ค. ์ดํ›„ routine์ด ํ˜ธ์ถœ๋  ๋•Œ arg๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ฒŒ ๋œ๋‹ค.

pthread_cleanup_pop() ํ•จ์ˆ˜๋Š” ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ ์Šคํƒ ์ƒ๋‹จ์˜ ๋ฃจํ‹ด์„ ์ œ๊ฑฐํ•˜๋ฉฐ, execute๊ฐ€ 0์ด ์•„๋‹ˆ๋ฉด ๊ทธ ๋ฃจํ‹ด์„ ์‹คํ–‰ํ•œ๋‹ค.

๋‹ค์Œ ๊ฒฝ์šฐ์— ์ทจ์†Œ ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๋“ค์„ ์Šคํƒ์—์„œ ๊บผ๋‚ด์„œ ์‹คํ–‰ํ•œ๋‹ค.

  1. ์Šค๋ ˆ๋“œ๊ฐ€ ์ทจ์†Œ๋  ๋•Œ ์Šคํƒ์— ์žˆ๋Š” ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๋“ค์„ ์Šคํƒ์— ์ง‘์–ด๋„ฃ์€ ์ˆœ์„œ ๋ฐ˜๋Œ€๋กœ ๊บผ๋‚ด์„œ ์‹คํ–‰ํ•œ๋‹ค.

  2. ์Šค๋ ˆ๋“œ๊ฐ€ pthread_exit(3) ํ˜ธ์ถœ๋กœ ์ข…๋ฃŒํ•  ๋•Œ ์•ž ํ•ญ๋ชฉ ์„ค๋ช…์ฒ˜๋Ÿผ ๋ชจ๋“  ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๋“ค์„ ์‹คํ–‰ํ•œ๋‹ค. (์Šค๋ ˆ๋“œ ์‹œ์ž‘ ํ•จ์ˆ˜์—์„œ return์„ ์ˆ˜ํ–‰ํ•ด์„œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค.)

  3. ์Šค๋ ˆ๋“œ๊ฐ€ 0 ์•„๋‹Œ execute ์ธ์ž๋กœ pthread_cleanup_pop()์„ ํ˜ธ์ถœํ•  ๋•Œ ์ตœ์ƒ๋‹จ์˜ ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๊บผ๋‚ด์„œ ์‹คํ–‰ํ•œ๋‹ค.

POSIX.1์—์„œ๋Š” pthread_cleanup_push()์™€ pthread_cleanup_pop()์„ ๊ฐ๊ฐ '{'์™€ '}'๋ฅผ ๋‹ด์€ ํ…์ŠคํŠธ๋กœ ํ™•์žฅ๋˜๋Š” ๋งคํฌ๋กœ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ํ•จ์ˆ˜๋“ค์˜ ํ˜ธ์ถœ์ด ๊ฐ™์€ ํ•จ์ˆ˜ ์•ˆ์— ์žˆ๋„๋ก, ๊ทธ๋ฆฌ๊ณ  ๊ฐ™์€ ๋ฌธ๋ฒ•์  ๋‚ดํฌ ๋‹จ๊ณ„์— ์žˆ๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค. (๋‹ฌ๋ฆฌ ๋งํ•˜๋ฉด ํŠน์ • ์ฝ”๋“œ ๊ตฌ๊ฐ„์„ ์˜ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ๋งŒ ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ๋‹ค.)

setjmp(3)(sigsetjmp(3))๋กœ ์ ํ”„ ๋ฒ„ํผ๋ฅผ ์ฑ„์šด ์ดํ›„์— ์ง์„ ์ด๋ฃจ๋Š” ํ˜ธ์ถœ ์—†์ด pthread_cleanup_push()๋‚˜ pthread_cleanup_pop()์„ ํ˜ธ์ถœํ•œ ์ƒํƒœ์—์„œ longjmp(3)(siglongjmp(3))๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ทœ์ •๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ ๋‚ด์—์„œ setjmp(3)(sigsetjmp(3))๋กœ ์ ํ”„ ๋ฒ„ํผ๋ฅผ ์ฑ„์šด ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ํ•ธ๋“ค๋Ÿฌ ๋‚ด์—์„œ longjmp(3)(siglongjmp(3)) ํ˜ธ์ถœ ์‹œ ๊ทœ์ •๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

RETURN VALUE

์ด ํ•จ์ˆ˜๋“ค์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.

ERRORS

์˜ค๋ฅ˜๊ฐ€ ์—†๋‹ค.

ATTRIBUTES

์ด ์ ˆ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์šฉ์–ด๋“ค์— ๋Œ€ํ•œ ์„ค๋ช…์€ attributes(7)๋ฅผ ๋ณด๋ผ.

์ธํ„ฐํŽ˜์ด์Šค ์†์„ฑ ๊ฐ’
pthread_cleanup_push(),
pthread_cleanup_pop()
์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ MT-Safe

CONFORMING TO

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

NOTES

๋ฆฌ๋ˆ…์Šค์—์„œ pthread_cleanup_push()์™€ pthread_cleanup_pop() ํ•จ์ˆ˜๋Š” ๊ฐ๊ฐ '{'์™€ '}'๋ฅผ ๋‹ด์€ ํ…์ŠคํŠธ๋กœ ํ™•์žฅ๋˜๋Š” ๋งคํฌ๋กœ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค. ์ด ํ•จ์ˆ˜๋“ค์˜ ํ˜ธ์ถœ ์ง ์•ˆ์—์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋“ค์ด ๊ทธ ์Šค์ฝ”ํ”„ ๋‚ด์—์„œ๋งŒ ๋ณด์ธ๋‹ค๋Š” ๋œป์ด๋‹ค.

POSIX.1์—์„œ๋Š” pthread_cleanup_push()์™€ pthread_cleanup_pop()์œผ๋กœ ๊ฐ์‹ผ ๋ธ”๋ก์„ return, break, continue, goto๋ฅผ ์ด์šฉํ•ด ๋„์ค‘์— ๋น ์ ธ๋‚˜๊ฐ€๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๊ทœ์ •๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๊ณ  ํ•œ๋‹ค. ์ด์‹ ๊ฐ€๋Šฅํ•œ ์‘์šฉ์—์„œ๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•ด์•ผ ํ•œ๋‹ค.

EXAMPLE

์•„๋ž˜ ํ”„๋กœ๊ทธ๋žจ์€ ์ด ํŽ˜์ด์ง€์—์„œ ๊ธฐ์ˆ ํ•˜๋Š” ํ•จ์ˆ˜๋“ค์˜ ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ ๋ฐฉ์‹์„ ๋ณด์—ฌ ์ค€๋‹ค. ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋งŒ๋“œ๋Š” ์Šค๋ ˆ๋“œ์—์„œ pthread_cleanup_push()์™€ pthread_cleanup_pop()์œผ๋กœ ๋‘˜๋Ÿฌ์‹ธ์ธ ๋ฃจํ”„๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ๊ทธ ๋ฃจํ”„์—์„œ๋Š” ์ „์—ญ ๋ณ€์ˆ˜ cnt๋ฅผ ์ดˆ๋‹น ํ•œ ๋ฒˆ์”ฉ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค. ์–ด๋–ค ๋ช…๋ นํ–‰ ์ธ์ž๋ฅผ ์ฃผ๋Š”๊ฐ€์— ๋”ฐ๋ผ์„œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ์ทจ์†Œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฃจํ”„๋ฅผ ๋น ์ ธ๋‚˜๊ฐ€์„œ (return์œผ๋กœ) ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒํ•˜๋„๋ก ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•œ๋‹ค.

๋‹ค์Œ ์…ธ ์„ธ์…˜์—์„œ๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—๊ฒŒ ์ทจ์†Œ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.

$ ./a.out
New thread started
cnt = 0
cnt = 1
Canceling thread
Called clean-up handler
Thread was canceled; cnt = 0

์Šค๋ ˆ๋“œ๊ฐ€ ์ทจ์†Œ๋˜๊ณ  ์ทจ์†Œ ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋ผ์„œ ์ „์—ญ ๋ณ€์ˆ˜ cnt์˜ ๊ฐ’์„ 0์œผ๋กœ ์žฌ์„ค์ •ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ ์‹คํ–‰์—์„œ๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ •์ƒ ์ข…๋ฃŒํ•˜๋„๋ก ๋ฉ”์ธ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•œ๋‹ค.

$ ./a.out x
New thread started
cnt = 0
cnt = 1
Thread terminated normally; cnt = 2

(cleanup_pop_arg๊ฐ€ 0์ด๋ฏ€๋กœ) ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์•˜๊ณ  ๊ทธ๋ž˜์„œ cnt ๊ฐ’์ด ์žฌ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ ์‹คํ–‰์—์„œ๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ •์ƒ ์ข…๋ฃŒํ•˜๋„๋ก ๋ฉ”์ธ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๊ณ  cleanup_pop_arg์— 0 ์•„๋‹Œ ๊ฐ’์„ ์ค€๋‹ค.

$ ./a.out x 1
New thread started
cnt = 0
cnt = 1
Called clean-up handler
Thread was canceled; cnt = 0

์Šค๋ ˆ๋“œ๊ฐ€ ์ทจ์†Œ๋˜์ง€ ์•Š์•˜์ง€๋งŒ pthread_cleanup_pop()์— 0 ์•„๋‹Œ ์ธ์ž๋ฅผ ์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ •๋ฆฌ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ ์†Œ์Šค

#include <pthread.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

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

static int done = 0;
static int cleanup_pop_arg = 0;
static int cnt = 0;

static void
cleanup_handler(void *arg)
{
    printf("Called clean-up handler\n");
    cnt = 0;
}

static void *
thread_start(void *arg)
{
    time_t start, curr;

    printf("New thread started\n");

    pthread_cleanup_push(cleanup_handler, NULL);

    curr = start = time(NULL);

    while (!done) {
        pthread_testcancel();           /* ์ทจ์†Œ์  */
        if (curr < time(NULL)) {
            curr = time(NULL);
            printf("cnt = %d\n", cnt);  /* ์ทจ์†Œ์  */
            cnt++;
        }
    }

    pthread_cleanup_pop(cleanup_pop_arg);
    return NULL;
}

int
main(int argc, char *argv[])
{
    pthread_t thr;
    int s;
    void *res;

    s = pthread_create(&thr, NULL, thread_start, NULL);
    if (s != 0)
        handle_error_en(s, "pthread_create");

    sleep(2);           /* ์ƒˆ ์Šค๋ ˆ๋“œ ์ž ์‹œ ๋Œ๋ฆฌ๊ธฐ */

    if (argc > 1) {
        if (argc > 2)
            cleanup_pop_arg = atoi(argv[2]);
        done = 1;

    } else {
        printf("Canceling thread\n");
        s = pthread_cancel(thr);
        if (s != 0)
            handle_error_en(s, "pthread_cancel");
    }

    s = pthread_join(thr, &res);
    if (s != 0)
        handle_error_en(s, "pthread_join");

    if (res == PTHREAD_CANCELED)
        printf("Thread was canceled; cnt = %d\n", cnt);
    else
        printf("Thread terminated normally; cnt = %d\n", cnt);
    exit(EXIT_SUCCESS);
}

SEE ALSO

pthread_cancel(3), pthread_cleanup_push_defer_np(3), pthread_setcancelstate(3), pthread_testcancel(3), pthreads(7)


2019-03-06

โš ๏ธ **GitHub.com Fallback** โš ๏ธ