pthread_getattr_np(3) - wariua/manpages-ko GitHub Wiki
pthread_getattr_np - μμ±λ μ€λ λμ μμ± μ»κΈ°
#define _GNU_SOURCE /* feature_test_macros(7) μ°Έκ³ */
#include <pthread.h>
int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);
-pthread
λ‘ μ»΄νμΌ λ° λ§ν¬.
pthread_getattr_np()
ν¨μλ attr
μ΄ κ°λ¦¬ν€λ μ€λ λ μμ± κ°μ²΄λ₯Ό λμ μ€μΈ μ€λ λ thread
λ₯Ό κΈ°μ νλ μ€μ μμ± κ°λ€μ λ΄λλ‘ μ€μ νλ€.
λ°νλλ μμ± κ°μ΄ pthread_create(3)μΌλ‘ μ€λ λλ₯Ό μμ±ν λ μΌλ attr
κ°μ²΄λ‘ μ λ¬ν λμ μμ± κ°κ³Ό λ€λ₯Ό μλ μλ€. νΉν λ€μ μμ±λ€μ΄ λ€λ₯Ό μ μλ€.
-
λΆλ¦¬ μν. μμ± ν ν©λ₯ κ°λ₯ μ€λ λκ° μ€μ€λ‘λ₯Ό λΆλ¦¬νμ μ μλ€.
-
μ€ν ν¬κΈ°. ꡬνμμ μ λΉν κ²½κ³λ‘ μ λ ¬νμ μ μλ€.
-
λ°©νΈ κ΅¬μ ν¬κΈ°. ꡬνμμ νμ΄μ§ ν¬κΈ°μ λ°°μλ‘ μ¬λ¦Ό ν μ μμΌλ©°, λλ μμ©μμ μ체μ μΌλ‘ μ€νμ ν λΉνλ κ²½μ° λ¬΄μν μ (μ¦ 0μΌλ‘ λ€λ£° μ) μλ€.
μ¬κΈ°μ λν΄μ, μ€λ λ μμ±μ μ°μΈ μ€λ λ μμ± κ°μ²΄μ μ€ν μ£Όμ μμ±μ΄ μ€μ λΌ μμ§ μμλ€λ©΄ ꡬνμμ κ·Έ μ€λ λμ κ³¨λΌ μ€ μ€μ μ€ν μ£Όμλ₯Ό λ°νλλ μ€λ λ μμ± κ°μ²΄κ° μλ € μ£Όκ² λλ€.
pthread_getattr_np()
κ° λ°νν μ€λ λ μμ± κ°μ²΄κ° λ μ΄μ νμνμ§ μμΌλ©΄ pthread_attr_destroy(3)λ‘ νκΈ°νλ κ² μ’λ€.
μ±κ³΅ μ μ΄ ν¨μλ€μ 0μ λ°ννλ€. μ€λ₯ μ 0 μλ μ€λ₯ λ²νΈλ₯Ό λ°ννλ€.
ENOMEM
- λ©λͺ¨λ¦¬ λΆμ‘±.
λλΆμ΄ thread
κ° λ©μΈ μ€λ λλ₯Ό κ°λ¦¬ν€λ κ²½μ°μλ μ¬λ¬ κΈ°λ° νΈμΆλ€μ μ€λ₯ λλ¬Έμ pthread_getattr_np()
κ° μ€ν¨ν μ μλ€. κ°λ Ή fopen(3)μ΄ /proc/self/maps
λ₯Ό μ΄ μ μκ±°λ getrlimit(2)κ° RLIMIT_STACK
μμ μ νμ μ§μνμ§ μλ κ²½μ°μ΄λ€.
glibc λ²μ 2.2.3λΆν° μ΄ ν¨μκ° μ¬μ© κ°λ₯νλ€.
μ΄ μ μμ μ¬μ©νλ μ©μ΄λ€μ λν μ€λͺ μ attributes(7)λ₯Ό 보λΌ.
μΈν°νμ΄μ€ | μμ± | κ° |
---|---|---|
pthread_getattr_np() |
μ€λ λ μμ μ± | MT-Safe |
μ΄ ν¨μλ€μ λΉνμ€ GNU νμ₯μ΄λ€. κ·Έλμ μ΄λ¦ λ€μ "_np"(nonportable: μ΄μμ± μμ)κ° λΆμ΄ μλ€.
μλ νλ‘κ·Έλ¨μ pthread_getattr_np()
μ¬μ© λ°©μμ λ³΄μ¬ μ€λ€. νλ‘κ·Έλ¨μμ μ€λ λλ₯Ό μμ±ν λ€μ pthread_getattr_np()
λ₯Ό μ΄μ©ν΄ λ°©νΈ κ΅¬μ ν¬κΈ°, μ€ν μ£Όμ, μ€ν ν¬κΈ° μμ±μ κ°μ Έμ νμνλ€. λͺ
λ Ήν μΈμλ₯Ό μ΄μ©ν΄ μ€λ λ μμ± μ κΈ°λ³Έκ³Ό λ€λ₯Έ κ°μΌλ‘ μ΄ μμ±λ€μ μ€μ ν μ μλ€. μλ μ
Έ μΈμ
μ νλ‘κ·Έλ¨ μ¬μ© λ°©μμ λ³΄μ¬ μ€λ€.
x86-32 μμ€ν μμ 첫 λ²μ§Έ μ€νμμλ κΈ°λ³Έ μμ±λ€λ‘ μ€λ λλ₯Ό λ§λ λ€.
$ ulimit -s # μ€ν μ ν μμ ==> κΈ°λ³Έ μ€ν ν¬κΈ° 2MB
unlimited
$ ./a.out
Attributes of created thread:
Guard size = 4096 bytes
Stack address = 0x40196000 (EOS = 0x40397000)
Stack size = 0x201000 (2101248) bytes
λ€μ μ€νμμλ λ°©νΈ κ΅¬μ ν¬κΈ°λ₯Ό μ§μ νλ©΄ μμ€ν νμ΄μ§ ν¬κΈ°(x86-32μμ 4096λ°μ΄νΈ)μ λ€μ λ² λ°°μλ‘ μ¬λ¦Ό λλ κ²μ λ³Ό μ μλ€.
$ ./a.out -g 4097
Thread attributes object after initializations:
Guard size = 4097 bytes
Stack address = (nil)
Stack size = 0x0 (0) bytes
Attributes of created thread:
Guard size = 8192 bytes
Stack address = 0x40196000 (EOS = 0x40397000)
Stack size = 0x201000 (2101248) bytes
λ§μ§λ§ μ€νμμλ μ€λ λλ₯Ό μν μ€νμ νλ‘κ·Έλ¨μμ μ§μ ν λΉνλ€. μ΄ κ²½μ° λ°©νΈ κ΅¬μ ν¬κΈ° μμ±μ΄ 무μλλ€.
$ ./a.out -g 4096 -s 0x8000 -a
Allocated thread stack at 0x804d000
Thread attributes object after initializations:
Guard size = 4096 bytes
Stack address = 0x804d000 (EOS = 0x8055000)
Stack size = 0x8000 (32768) bytes
Attributes of created thread:
Guard size = 0 bytes
Stack address = 0x804d000 (EOS = 0x8055000)
Stack size = 0x8000 (32768) bytes
#define _GNU_SOURCE /* pthread_getattr_np() μ μΈμ μν΄ */
#include <pthread.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 void
display_stack_related_attributes(pthread_attr_t *attr, char *prefix)
{
int s;
size_t stack_size, guard_size;
void *stack_addr;
s = pthread_attr_getguardsize(attr, &guard_size);
if (s != 0)
handle_error_en(s, "pthread_attr_getguardsize");
printf(%sGuard size = %d bytes\n", prefix, guard_size);
s = pthread_attr_getstack(attr, &stack_addr, &stack_size);
if (s != 0)
handle_error_en(s, "pthread_attr_getstack");
printf("%sStack address = %p", prefix, stack_addr);
if (stack_size > 0)
printf(" (EOS = %p)", (char *) stack_addr + stack_size);
printf("\n");
printf("%sStack size = 0x%x (%d) bytes\n",
prefix, stack_size, stack_size);
}
static void
display_thread_attributes(pthread_t thread, char *prefix)
{
int s;
pthread_attr_t attr;
s = pthread_getattr_np(thread, &attr);
if (s != 0)
handle_error_en(s, "pthread_getattr_np");
display_stack_related_attributes(&attr, prefix);
s = pthread_attr_destroy(&attr);
if (s != 0)
handle_error_en(s, "pthread_attr_destroy");
}
static void * /* μμ±ν μ€λ λμ μμ ν¨μ */
thread_start(void *arg)
{
printf("Attributes of created thread:\n");
display_thread_attributes(pthread_self(), "\t");
exit(EXIT_SUCCESS); /* λͺ¨λ μ€λ λ μ’
λ£ */
}
static void
usage(char *pname, char *msg)
{
if (msg != NULL)
fputs(msg, stderr);
fprintf(stderr, "Usage: %s [-s stack-size [-a]]"
" [-g guard-size]\n", pname);
fprintf(stderr, "\t\t-a means program should allocate stack\n");
exit(EXIT_FAILURE);
}
static pthread_attr_t * /* λͺ
λ Ήνμμ μ€λ λ μμ± μ»κΈ° */
get_thread_attributes_from_cl(int argc, char *argv[],
pthread_attr_t *attrp)
{
int s, opt, allocate_stack;
long stack_size, guard_size;
void *stack_addr;
pthread_attr_t *ret_attr_p = NULL; /* μ€λ λ μμ± κ°μ²΄λ₯Ό μ΄κΈ°ν
νλ κ²½μ° attrpλ‘ μ€μ */
allocate_stack = 0;
stack_size = -1;
guard_size = -1;
while ((opt = getopt(argc, argv, "ag:s:")) != -1) {
switch (opt) {
case 'a': allocate_stack = 1; break;
case 'g': guard_size = strtoul(optarg, NULL, 0); break;
case 's': stack_size = strtoul(optarg, NULL, 0); break;
default: usage(argv[0], NULL);
}
}
if (allocate_stack && stack_size == -1)
usage(argv[0], "Specifying -a without -s makes no sense\n");
if (argc > optind)
usage(argv[0], "Extraneous command-line arguments\n");
if (stack_size >= 0 || guard_size > 0) {
ret_attrp = attrp;
s = pthread_attr_init(attrp);
if (s != 0)
handle_error_en(s, "pthread_attr_init");
}
if (stack_size >= 0) {
if (!allocate_stack) {
s = pthread_attr_setstacksize(attrp, stack_size);
if (s != 0)
handle_error_en(s, "pthread_attr_setstacksize");
} else {
s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
stack_size);
if (s != 0)
handle_error_en(s, "posix_memalign");
printf("Allocated thread stack at %p\n\n", stack_addr);
s = pthread_attr_setstack(attrp, stack_addr, stack_size);
if (s != 0)
handle_error_en(s, "pthread_attr_setstacksize");
}
}
if (guard_size >= 0) {
s = pthread_attr_setguardsize(attrp, guard_size);
if (s != 0)
handle_error_en(s, "pthread_attr_setstacksize");
}
return ret_attrp;
}
int
main(int argc, char *argv[])
{
int s;
pthread_t thr;
pthread_attr_t attr;
pthread_attr_t *attrp = NULL; /* μ€λ λ μμ± κ°μ²΄λ₯Ό μ΄κΈ°ν
νλ κ²½μ° &attrλ‘ μ€μ */
attrp = get_thread_attributes_from_cl(argc, argv, &attr);
if (attrp != NULL) {
printf("Thread attributes object after initializations:\n");
display_stack_related_attributes(attrp, "\t");
printf("\n");
}
s = pthread_create(&thr, attrp, &thread_start, NULL);
if (s != 0)
handle_error_en(s, "pthread_create");
if (attrp != NULL) {
s = pthread_attr_destroy(attrp);
if (s != 0)
handle_error_en(s, "pthread_attr_destroy");
}
pause(); /* λ€λ₯Έ μ€λ λμμ exit() νΈμΆν λ μ’
λ£ */
}
pthread_attr_getaffinity_np(3), pthread_attr_getdetachstate(3), pthread_attr_getguardsize(3), pthread_attr_getinheritsched(3), pthread_attr_getschedparam(3), pthread_attr_getschedpolicy(3), pthread_attr_getscope(3), pthread_attr_getstack(3), pthread_attr_getstackaddr(3), pthread_attr_getstacksize(3), pthread_attr_init(3), pthread_create(3), pthreads(7)
2019-03-06