pthread_cleanup_push(3) - wariua/manpages-ko GitHub Wiki
pthread_cleanup_push, pthread_cleanup_pop - ์ค๋ ๋ ์ทจ์ ์ ๋ฆฌ ํธ๋ค๋ฌ ์ง์ด๋ฃ๊ธฐ์ ๊บผ๋ด๊ธฐ
#include <pthread.h>
void pthread_cleanup_push(void (*routine)(void *),
void *arg);
void pthread_cleanup_pop(int execute);
-pthread
๋ก ๋งํฌ.
์ด ํจ์๋ค์ ํธ์ถ ์ค๋ ๋์ ์ค๋ ๋ ์ทจ์ ์ ๋ฆฌ ํธ๋ค๋ฌ ์คํ์ ์กฐ์ํ๋ค. ์ ๋ฆฌ ํธ๋ค๋ฌ๋ ์ค๋ ๋๊ฐ ์ทจ์๋ ๋ (๋๋ ์๋์์ ์ค๋ช ํ๋ ์ฌ๋ฌ ๋ค๋ฅธ ๊ฒฝ์ฐ์) ์๋์ผ๋ก ์คํ๋๋ ํจ์์ด๋ค. ์๋ฅผ ๋ค์ด ํธ๋ค๋ฌ์์ ๋ฎคํ ์ค๋ฅผ ๋์์ ํ๋ก์ธ์ค ๋ด ๋ค๋ฅธ ์ค๋ ๋๋ค์๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํ๊ฒ ํ ์ ์์ ๊ฒ์ด๋ค.
pthread_cleanup_push()
ํจ์๋ ์ ๋ฆฌ ํธ๋ค๋ฌ ์คํ ์๋จ์ routine
์ ์ง์ด๋ฃ๋๋ค. ์ดํ routine
์ด ํธ์ถ๋ ๋ arg
๋ฅผ ์ธ์๋ก ๋ฐ๊ฒ ๋๋ค.
pthread_cleanup_pop()
ํจ์๋ ์ ๋ฆฌ ํธ๋ค๋ฌ ์คํ ์๋จ์ ๋ฃจํด์ ์ ๊ฑฐํ๋ฉฐ, execute
๊ฐ 0์ด ์๋๋ฉด ๊ทธ ๋ฃจํด์ ์คํํ๋ค.
๋ค์ ๊ฒฝ์ฐ์ ์ทจ์ ์ ๋ฆฌ ํธ๋ค๋ฌ๋ค์ ์คํ์์ ๊บผ๋ด์ ์คํํ๋ค.
-
์ค๋ ๋๊ฐ ์ทจ์๋ ๋ ์คํ์ ์๋ ์ ๋ฆฌ ํธ๋ค๋ฌ๋ค์ ์คํ์ ์ง์ด๋ฃ์ ์์ ๋ฐ๋๋ก ๊บผ๋ด์ ์คํํ๋ค.
-
์ค๋ ๋๊ฐ pthread_exit(3) ํธ์ถ๋ก ์ข ๋ฃํ ๋ ์ ํญ๋ชฉ ์ค๋ช ์ฒ๋ผ ๋ชจ๋ ์ ๋ฆฌ ํธ๋ค๋ฌ๋ค์ ์คํํ๋ค. (์ค๋ ๋ ์์ ํจ์์์
return
์ ์ํํด์ ์ค๋ ๋๊ฐ ์ข ๋ฃํ๋ ๊ฒฝ์ฐ์๋ ์ ๋ฆฌ ํธ๋ค๋ฌ๊ฐ ํธ์ถ๋์ง ์๋๋ค.) -
์ค๋ ๋๊ฐ 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)) ํธ์ถ ์ ๊ท์ ๋์ด ์์ง ์์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
์ด ํจ์๋ค์ ๊ฐ์ ๋ฐํํ์ง ์๋๋ค.
์ค๋ฅ๊ฐ ์๋ค.
์ด ์ ์์ ์ฌ์ฉํ๋ ์ฉ์ด๋ค์ ๋ํ ์ค๋ช ์ attributes(7)๋ฅผ ๋ณด๋ผ.
์ธํฐํ์ด์ค | ์์ฑ | ๊ฐ |
---|---|---|
pthread_cleanup_push() ,pthread_cleanup_pop()
|
์ค๋ ๋ ์์ ์ฑ | MT-Safe |
POSIX.1-2001, POSIX.1-2008.
๋ฆฌ๋
์ค์์ pthread_cleanup_push()
์ pthread_cleanup_pop()
ํจ์๋ ๊ฐ๊ฐ '{
'์ '}
'๋ฅผ ๋ด์ ํ
์คํธ๋ก ํ์ฅ๋๋ ๋งคํฌ๋ก๋ก ๊ตฌํ๋์ด ์๋ค. ์ด ํจ์๋ค์ ํธ์ถ ์ง ์์์ ์ ์ธํ ๋ณ์๋ค์ด ๊ทธ ์ค์ฝํ ๋ด์์๋ง ๋ณด์ธ๋ค๋ ๋ป์ด๋ค.
POSIX.1์์๋ pthread_cleanup_push()
์ pthread_cleanup_pop()
์ผ๋ก ๊ฐ์ผ ๋ธ๋ก์ return
, break
, continue
, goto
๋ฅผ ์ด์ฉํด ๋์ค์ ๋น ์ ธ๋๊ฐ๋ ๊ฒฐ๊ณผ๊ฐ ๊ท์ ๋์ด ์์ง ์๋ค๊ณ ํ๋ค. ์ด์ ๊ฐ๋ฅํ ์์ฉ์์๋ ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ์ ํผํด์ผ ํ๋ค.
์๋ ํ๋ก๊ทธ๋จ์ ์ด ํ์ด์ง์์ ๊ธฐ์ ํ๋ ํจ์๋ค์ ๊ฐ๋จํ ์ฌ์ฉ ๋ฐฉ์์ ๋ณด์ฌ ์ค๋ค. ํ๋ก๊ทธ๋จ์์ ๋ง๋๋ ์ค๋ ๋์์ 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);
}
pthread_cancel(3), pthread_cleanup_push_defer_np(3), pthread_setcancelstate(3), pthread_testcancel(3), pthreads(7)
2019-03-06