Pthread API ·¹ÆÛ·±½º
ÃÑ ÆäÀÌÁö ¼ö : 3027

Àüü ÇÔ¼ö/¿ë¾î»çÀü
ÇöÀçÀ§Ä¡ : ¹Ì´Ï»çÀÌÆ®>Thread>Beginning>PthreadApiReference
Docbook ¿ø¹®

Pthread API Reference

Pthread API Reference

À± »ó¹è

고친 과정
고침 0.92004³â 6¿ù 30ÀÏ 12½Ã
pthread Ãë¼Ò°ü·Ã api Ãß°¡
고침 0.82003³â 10¿ù 9ÀÏ 12½Ã
pthread ½Ã±×³Î °ü·Ã api Ãß°¡

1. ¼Ò°³

ÀÌ ¹®¼­´Â pthread ·¹ÆÛ·±½º ¹®¼­ÀÌ´Ù. pthread ¿¡¼­ Á¦°øÇÏ´Â ¸ðµç ÇÔ¼öÀÇ ·¹ÆÛ·±½º¸¦ Á¦°øÇϰí ÀÖÁö´Â ¾ÊÁö¸¸, ÀÚÁÖ ¾²Àϸ¸ÇÑ ´ëºÎºÐÀÇ ÇÔ¼öµéÀº Á¤¸®µÇ¾î ÀÖÀ½À¸·Î Âü°íÇÒ¸¸ÇÑ °¡Ä¡°¡ ÀÖÀ»°ÍÀÌ´Ù.

ÀÌ ¹®¼­¿¡ ºüÁø ³»¿ëµéÀº °è¼Ó Ãß°¡ÇØ ³ª°¥ ¿¹Á¤ÀÌ´Ù.


2. ±âº» ¾²·¹µå ÇÔ¼ö

ÁÖ·Î ¾²·¹µå »ý¼º°ú Á¾·á¿¡ °ü·ÃµÈ °¡Àå ±âº»ÀûÀÎ ÇÔ¼öµéÀÌ´Ù.


2.1. pthread_create

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine)(void *), void *arg);
			
¾²·¹µå »ý¼ºÀ» À§Çؼ­ »ç¿ëÇÑ´Ù. ù¹øÂ° ¾Æ±Ô¸ÕÆ®ÀÎ thread ´Â ¾²·¹µå°¡ ¼º°øÀûÀ¸·Î »ý¼ºµÇ¾úÀ»¶§ »ý¼ºµÈ ¾²·¹µå¸¦ ½Äº°Çϱâ À§Çؼ­ »ç¿ëµÇ´Â ¾²·¹µå ½Äº°ÀÚÀÌ´Ù. µÎ¹øÂ° ¾Æ±Ô¸ÕÆ®ÀÎ attr Àº ¾²·¹µå Ư¼ºÀ» ÁöÁ¤Çϱâ À§Çؼ­ »ç¿ëÇϸç, ±âº» ¾²·¹µå Ư¼ºÀ» ÀÌ¿ëÇϰíÀÚ ÇÒ°æ¿ì¿¡ NULL À» »ç¿ëÇÑ´Ù. 3¹øÂ° ¾Æ±Ô¸ÕÆ®ÀÎ start_routine´Â ºÐ±â½ÃÄѼ­ ½ÇÇàÇÒ ¾²·¹µå ÇÔ¼öÀ̸ç, 4¹øÂ° ¾Æ±Ô¸Õ´ÂÀÎ arg´Â ¾²·¹µå ÇÔ¼öÀÇ ÀÎÀÚÀÌ´Ù.

¼º°øÀûÀ¸·Î »ý¼ºµÉ°æ¿ì 0À» ¸®ÅÏÇÑ´Ù.

¿¹Á¦ : pthread_create.cc

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

// ¾²·¹µå ÇÔ¼ö
void *t_function(void *data)
{
    int id;
    int i = 0;
    id = *((int *)data);

    while(1)
    {
        printf("%d : %d\n", id, i);
        i++;
        sleep(1);
    }
}

int main()
{
    pthread_t p_thread[2];
    int thr_id;
    int status;
    int a = 1;
    int b = 2;

    // ¾²·¹µå »ý¼º ¾Æ±Ô¸ÕÆ®·Î 1 À» ³Ñ±ä´Ù.  
    thr_id = pthread_create(&p_thread[0], NULL, t_function, (void *)&a);
    if (thr_id < 0)
    {
        perror("thread create error : ");
        exit(0);
    }

    // ¾²·¹µå »ý¼º ¾Æ±Ô¸ÕÆ®·Î 2 ¸¦ ³Ñ±ä´Ù. 
    thr_id = pthread_create(&p_thread[1], NULL, t_function, (void *)&b);
    if (thr_id < 0)
    {
        perror("thread create error : ");
        exit(0);
    }

    // ¾²·¹µå Á¾·á¸¦ ±â´Ù¸°´Ù. 
    pthread_join(p_thread[0], (void **)&status);
    pthread_join(p_thread[1], (void **)&status);

    return 0;
}
			
½ÇÇàµÈ ¾²·¹µå¿¡ ´ëÇØ¼­´Â pthread_join µîÀÇ ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ¾²·¹µå Á¾·á¶§±îÁö ±â´Ù·ÁÁà¾ß ÇÑ´Ù. ptherad_join Àº ÀÏÁ¾ÀÇ fork ÀÇ wait ¿Í ºñ½ÁÇÏ°Ô ÀÛµ¿Çϸç, ¾²·¹µåÀÚ¿øÀ» ÇØÁ¦ ½ÃÄÑÁØ´Ù.


2.2. pthread_join

#include <pthread.h>
int pthread_join(pthread_t th, void **thread_return);
			
ù¹øÂ° ¾Æ±Ô¸ÕÆ® th´Â ±â´Ù¸±(join)ÇÒ ¾²·¹µå ½Äº°ÀÚÀ̸ç, µÎ¹øÂ° ¾Æ±Ô¸ÕÆ® thread_returnÀº ¾²·¹µåÀÇ ¸®ÅÏ(return) °ªÀÌ´Ù. thread_return ÀÌ NULL ÀÌ ¾Æ´Ò°æ¿ì ÇØ´Ù Æ÷ÀÎÅÍ·Î ¾²·¹µå ¸®ÅÏ °ªÀ» ¹Þ¾Æ¿Ã¼ö ÀÖ´Ù.

pthread_joinc.c

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

// ¾²·¹µå ÇÔ¼ö 
// 1Ãʸ¦ ±â´Ù¸°ÈÄ ¾Æ±Ô¸ÕÆ®^2 À» ¸®ÅÏÇÑ´Ù. 
void *t_function(void *data)
{
    int num = *((int *)data);
    printf("num %d\n", num);
    sleep(1);
    return (void *)(num*num);
}

int main()
{
    pthread_t p_thread;
    int thr_id;
    int status;
    int a = 100;

    thr_id = pthread_create(&p_thread, NULL, t_function, (void *)&a);
    if (thr_id < 0)
    {
        perror("thread create error : ");
        exit(0);
    }
    // ¾²·¹µå ½Äº°ÀÚ p_thread °¡ Á¾·áµÇ±æ ±â´Ù·È´Ù°¡ 
    // Á¾·á¸®ÅϰªÀ» °¡Á®¿Â´Ù. 
    pthread_join(p_thread, (void *)&status);
    printf("thread join : %d\n", status);

    return 0;
}
			


2.3. pthread_detach

int pthread_detach(pthread_t th);
			
detach ´Â "¶¼¾î³»´Ù" ¶ó´Â ¶æÀ» °¡Áö¸ç main ¾²·¹µå¿¡¼­ pthread_create ¸¦ ÀÌ¿ëÇØ »ý¼ºµÈ ¾²·¹µå¸¦ ºÐ¸®½ÃŲ´Ù. ÀÌ ÇÔ¼ö´Â ½Äº°¹øÈ£thÀÎ ¾²·¹µå¸¦ detach ½Ã۴µ¥, detach µÇ¾úÀ»°æ¿ì ÇØ´ç(detach µÈ) ¾²·¹µå°¡ Á¾·áµÉ°æ¿ì pthread_joinc À» È£ÃâÇÏÁö ¾Ê´õ¶óµµ Áï½Ã ¸ðµç ÀÚ¿øÀÌ ÇØÁ¦(free) µÈ´Ù.

¿©±â¿¡¼­´Â pthread_create È£ÃâÈÄ detach ÇÏ´Â ¹æ¹ýÀ» ¼³¸íÇϰí Àִµ¥, pthread_create È£Ãâ½Ã¿¡ ¾²·¹µå°¡ detach µÇµµ·Ï ÇÒ¼öµµ ÀÖ´Ù. ÀÌ¿¡ ´ëÇÑ ³»¿ëÀº pthread_attr_setdetachstate ¸¦ ´Ù·ç¸é¼­ ¼³¸íÇϵµ·Ï ÇϰڴÙ.

¿¹Á¦ : pthread_detach.c

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

// ¾²·¹µå ÇÔ¼ö
// 1Ãʸ¦ ±â´Ù¸°ÈÄ ¾Æ±Ô¸ÕÆ®^2 À» ¸®ÅÏÇÑ´Ù.
void *t_function(void *data)
{
    char a[100000];
    int num = *((int *)data);
	printf("Thread Start\n");
    sleep(5);
	printf("Thread end\n");
}

int main()
{
    pthread_t p_thread;
    int thr_id;
    int status;
    int a = 100;

	printf("Before Thread\n"); 
    thr_id = pthread_create(&p_thread, NULL, t_function, (void *)&a);
    if (thr_id < 0)
    {
        perror("thread create error : ");
        exit(0);
    }
    // ½Äº°¹øÈ£ p_thread ¸¦ °¡Áö´Â ¾²·¹µå¸¦ detach 
    // ½ÃÄÑÁØ´Ù. 
    pthread_detach(p_thread);
    pause();
    return 0;
}
			
À§ÀÇ ½î¾² Äڵ忡¼­ detach ½ÃÄ×À»¶§¿Í ±×·¸Áö ¾Ê¾ÒÀ»¶§ÀÇ ¸Þ¸ð¸® »óȲÀ» ºñ±³Çغ¸±â ¹Ù¶õ´Ù. detatach ¸¦ ÇßÀ»°æ¿ì ÇÁ·Î¼¼½ºÀÇ ¸Þ¸ð¸® »ç¿ëÀ²°ú detache ¸¦ ÁÖ¼® ó¸®ÇßÀ»°æ¿ìÀÇ ¸Þ¸ð¸® »ç¿ëÀ²ÀÇ º¯È­¸¦ ¼­·Î ºñ±³Çغ¸¸é µÇ´Âµ¥, detach ¸¦ »ç¿ëÇÏÁö ¾Ê¾ÒÀ»°æ¿ì t_function ÀÌ Á¾·á°¡ µÇ´õ¶óµµ ÀÚ¿øÀÌ ÇØÁ¦µÇÁö ¾ÊÀ½À» º¼¼ö ÀÖÀ»°ÍÀÌ´Ù. Å×½ºÆ®´Â °£´ÜÇÑ ½ºÅ©¸³Æ®¸¦ ÀÌ¿ëÇϵµ·Ï ÇÑ´Ù.
[root@localhost test]# while [ 1 ]; do ps -aux | grep pthread | grep -v grep | grep -v vim; sleep 1; done
root      2668  0.0  0.1  1436  292 pts/8    S    18:37   0:00 ./pthread_detach
root      2668  0.0  0.1  1436  292 pts/8    S    18:37   0:00 ./pthread_detach
			
À§ÀÇ ps ³»¿ë¿¡¼­ 5¹øÂ° ÇʵåÀÇ º¯È­¸¦ È®ÀÎÇÏ¸é µÈ´Ù.


2.4. pthread_exit

void pthread_exit(void *retval);
			
pthread_exit ´Â ÇöÀç ½ÇÇàÁßÀÎ ¾²·¹µå¸¦ Á¾·á½Ã۰íÀÚ ÇÒ¶§ »ç¿ëÇÑ´Ù. ¸¸¾à pthread_cleanup_push °¡ Á¤ÀǵǾî ÀÖ´Ù¸é, pthread_exit °¡ È£ÃâµÉ°æ¿ì cleanup handler °¡ È£ÃâµÈ´Ù. º¸Åë ÀÌ cleanup handler Àº ¸Þ¸ð¸®¸¦ Á¤¸®ÇÏ´Â µîÀÇ ÀÏÀ» ÇÏ°Ô µÈ´Ù.

¿¹Á¦ : pthread_exit.c

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

// ¾²·¹µå ÇÔ¼ö
// 1Ãʸ¦ ±â´Ù¸°ÈÄ ¾Æ±Ô¸ÕÆ®^2 À» ¸®ÅÏÇÑ´Ù.
void *t_function(void *data)
{
    int num = *((int *)data);
    int i = 0;
    while(1)
    {
        if (i == 3)
            pthread_exit(0);
        printf("loop %d\n", i);
        i++;
        sleep(1);
    }
}

int main()
{
    pthread_t p_thread;
    int thr_id;
    int status;
    int a = 100;


    thr_id = pthread_create(&p_thread, NULL, t_function, (void *)&a);
    if (thr_id < 0)
    {
        perror("thread create error : ");
        exit(0);
    }
    pthread_join(p_thread, (void **)&status);
    return 0;
}
			


2.5. pthread_cleanup_push

void pthrad_cleanup_push(void (*routine) (void *), void *arg);
			
À̰ÍÀº cleanup handlers ¸¦ ÀνºÅçÇϱâ À§Çؼ­ »ç¿ëµÈ´Ù. pthread_exit(3) °¡ È£ÃâµÇ¾î¼­ ¾²·¹µå°¡ Á¾·áµÉ¶§ pthread_cleanup_push ¿¡ ÀÇÇØ¼­ ÀνºÅçµÈ ÇÔ¼ö°¡ È£ÃâµÈ´Ù. routineÀÌ ¾²·¹µå°¡ Á¾·áµÉ¶§ È£ÃâµÇ´Â ÇÔ¼öÀÌ´Ù. arg´Â ¾Æ±Ô¸ÕÆ®ÀÌ´Ù.

cleanup handlers ´Â ÁÖ·Î ÀÚ¿øÀ» µÇµ¹·ÁÁְųª, mutex Àá±ÝµîÀÇ ÇØÁ¦¸¦ À§ÇÑ ¿ëµµ·Î »ç¿ëµÈ´Ù. ¸¸¾à mutex ¿µ¿ª¿¡¼­ pthread_exit °¡ È£ÃâµÇ¾î ¹ö¸±°æ¿ì ´Ù¸¥¾²·¹µå¿¡¼­ ¿µ¿øÈ÷ block µÉ¼ö Àֱ⠶§¹®ÀÌ´Ù. ¶ÇÇÑ malloc À¸·Î ÇÒ´ç¹ÞÀº ¸Þ¸ð¸®, ¿­¸° ÆÄÀÏÁöÁ¤ÀÚ¸¦ ´Ý±â À§Çؼ­µµ »ç¿ëÇÑ´Ù.

¿¹Á¦ : pthread_cleanup.c

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

// ¾²·¹µå ÇÔ¼ö
// 1Ãʸ¦ ±â´Ù¸°ÈÄ ¾Æ±Ô¸ÕÆ®^2 À» ¸®ÅÏÇÑ´Ù.
//

char *mydata;
void cleanup(void *);
void *t_function(void *data)
{
    int num = *((int *)data);
    int i = 0;
    int a = 1;
    // cleanup handler ·Î cleanup ÇÔ¼ö¸¦ 
    // ÁöÁ¤ÇÑ´Ù. 
    pthread_cleanup_push(cleanup, (void *)&a);
    mydata = (char *)malloc(1000);
    while(1)
    {
        if (i == 3)
        {
            // pthread_exit °¡ È£ÃâµÇ¸é¼­ 
            // cleanup À» È£ÃâÇÏ°Ô µÈ´Ù. 
            pthread_exit(0);
            return 1;
        }
        printf("loop %d\n", i);
        i++;
        sleep(1);
    }
    pthread_cleanup_pop(0);
}


int main()
{
    pthread_t p_thread;
    int thr_id;
    int status;
    int a = 100;


    thr_id = pthread_create(&p_thread, NULL, t_function, (void *)&a);
    if (thr_id < 0)
    {
        perror("thread create error : ");
        exit(0);
    }
    pthread_join(p_thread, (void **)&status);
    printf("Join finish\n");
}

// cleanup handler
void cleanup(void *myarg)
{
    printf("thread is clean up\n");
    printf("resource free\n");
    free(mydata);
}
			


2.6. pthread_cleanup_pop

pthread_cleanup_push ¿Í ÇÔ²² »ç¿ëµÇ¸ç, install µÈ cleanup handler À» Á¦°ÅÇϱâ À§Çؼ­ »ç¿ëµÈ´Ù.

void pthread_cleanup_pop(int execute);
			
¸¸¾à execute °¡ 0 À̶ó¸é, pthread_cleanup_push ¿¡ ÀÇÇØ ÀνºÅçµÈ cleanup handler ¸¦ (½ÇÇà½ÃŰÁö ¾Ê°í)»èÁ¦¸¸ ½ÃŲ´Ù. 0 ÀÌ ¾Æ´Ñ ¼ýÀÚ¶ó¸é cleanup handler À» ½ÇÇà½ÃŰ°í »èÁ¦ µÈ´Ù. »ç¿ë¿¹Á¦´Â 2.5절À» Âü°íÇ϶ó.

±×¸®°í pthread_cleanup_push ¿Í pthread_cleanup_pop Àº ¹Ýµå½Ã °°Àº ÇÔ¼ö³»ÀÇ °°Àº ·¹º§ÀÇ ºí·°¿¡¼­ ÇѽÖÀ¸·Î »ç¿ëÇØ¾ß ÇÑ´Ù.


2.7. pthread_self

pthread_t pthread_self(void);
			
pthread_self¸¦ È£ÃâÇÏ´Â ÇöÀç ¾²·¡µåÀÇ ¾²·¹µå½Äº°ÀÚ¸¦ µÇµ¹·ÁÁØ´Ù.

¿¹Á¦ : pthread_self.c

#include <pthread.h>
#include <stdio.h>

void *func(void *a)
{
    pthread_t id;
    id = pthread_self();
    printf("->%d\n", id);
}

int main(int argc, char **argv)
{
    pthread_t p_thread;
    pthread_create(&p_thread, NULL, func, (void *)NULL);
    printf("%d\n", p_thread);
    pthread_create(&p_thread, NULL, func, (void *)NULL);
    printf("%d\n", p_thread);

	return 1;
}
			


3. ¾²·¹µå µ¿±âÈ­ ÇÔ¼ö

¾²·¹µå µ¿±âÈ­¿Í °ü·ÃµÈ ÇÔ¼öµéÀÌ´Ù.


3.1. pthread_mutex_init

int pthread_mutex_init(pthread_mutex_t * mutex, 
           const pthread_mutex_attr *attr); 
			
mutex ´Â ¿©·¯°³ÀÇ ¾²·¹µå°¡ °øÀ¯ÇÏ´Â µ¥ÀÌŸ¸¦ º¸È£Çϱâ À§Çؼ­ »ç¿ëµÇ´Â µµ±¸·Î½á, º¸È£ÇϰíÀÚ ÇÏ´Â µ¥ÀÌŸ¸¦ ´Ù·ç´Â Äڵ念¿ªÀ» ´ÜÁö Çѹø¿¡ ÇϳªÀÇ ¾²·¹µå¸¸ ½ÇÇà°¡´É Çϵµ·Ï ÇÏ´Â ¹æ¹ýÀ¸·Î °øÀ¯µÇ´Â µ¥ÀÌŸ¸¦ º¸È£ÇÑ´Ù. ÀÌ·¯ÇÑ Äڵ念¿ª(ÇϳªÀÇ ¾²·¹µå¸¸ Á¡À¯°¡´ÉÇÑ)À» critical section À̶ó°í Çϸç, mutex °ü·Ã API ¸¦ ÀÌ¿ëÇØ¼­ °ü¸®ÇÒ¼ö ÀÖ´Ù.

pthread_mutex_init ´Â mutex °´Ã¼¸¦ ÃʱâÈ­ ½Ã۱â À§Çؼ­ »ç¿ëÇÑ´Ù. ù¹øÂ° ÀÎÀÚ·Î ÁÖ¾îÁö´Â mutex °´Ã¼ mutex¸¦ ÃʱâÈ­½Ã۸ç, µÎ¹øÂ° ÀÎÀÚÀÎ attr ¸¦ ÀÌ¿ëÇØ¼­ mutex Ư¼ºÀ» º¯°æÇÒ¼ö ÀÖ´Ù. ±âº» mutex Ư¼ºÀ» ÀÌ¿ëÇϱ⠿øÇÑ´Ù¸é NULL À» »ç¿ëÇÏ¸é µÈ´Ù.

mutex Ư¼º(Á¾·ù) ¿¡´Â "fast", "recurisev", "error checking" ÀÇ Á¾·ù°¡ ÀÖÀ¸¸ç, ±âº»À¸·Î "fast" °¡ »ç¿ëµÈ´Ù.

// ¹ÂÅØ½º °´Ã¼ ¼±¾ð
pthread_mutex_t mutex_lock;
...
void *t_function()
{
    pthread_mutex_lock(&mutex_lock);
    // critical section
    pthread_mutex_unlock(&mutex_lock);
}
int main()
{
    pthread_t p_thread;
    int state;
    // ¹ÂÅØ½º °´Ã¼ ÃʱâÈ­, ±âº» Ư¼ºÀ¸·Î ÃʱâÈ­ ÇßÀ½
    pthread_mutex_init(&mutex_lock, NULL);
    pthread_create(&p_thread, NULL, t_function, (void *)&a);
    ...
    pthread_joinc(&p_thread, (void **)&status);
}
			


3.2. pthread_mutex_destory

int pthread_mutex_destory(pthread_mutex_t *mutex);
			
ÀÎÀÚ·Î ÁÖ¾îÁø ¹ÂÅØ½º °´Ã¼ mutex ¸¦ Á¦°ÅÇϱâ À§Çؼ­ »ç¿ëµÈ´Ù. mutex ´Â pthread_mutex_init()ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ »ý¼ºµÈ ¹ÂÅØ½º °´Ã¼ÀÌ´Ù.

pthread_mutex_destory ¸¦ ÀÌ¿ëÇØ¼­ Á¦´ë·Î mutex ¸¦ »èÁ¦ÇÏ·Á¸é ÀÌ mutex ´Â ¹Ýµå½Ã unlock »óÅÂÀÌ¿©¾ß ÇÑ´Ù.


3.3. pthread_mutex_lock

int pthread_mutex_lock(pthread_mutex_t *mutex);
			
pthread_mutex_lock ´Â critcal section ¿¡ µé¾î°¡±â À§Çؼ­ mutex lock À» ¿äûÇÑ´Ù. ¸¸¾à ÀÌ¹Ì ´Ù¸¥ ¾²·¹µå¿¡¼­ mutex lock ¸¦ ¾ò¾î¼­ »ç¿ëÇϰí ÀÖ´Ù¸é ´Ù¸¥ ¾²·¹µå¿¡¼­ mutex lock(¹ÂÅØ½º Àá±Ý) À» ÇØÁ¦ÇÒ¶§±îÁö(»ç¿ëÇÒ¼ö ÀÖÀ»¶§±îÁö) ºí·° µÈ´Ù.

¸¸¾à ´Ù¸¥ ¾î¶² ¾²·¹µå¿¡¼­µµ mutex lock À» »ç¿ëÇϰí ÀÖÁö ¾Ê´Ù¸é, Áï½Ã mutex lock À» ¾òÀ»¼ö ÀÖ°Ô µÇ°í critcal section ¿¡ ÁøÀÔÇÏ°Ô µÈ´Ù. critcal section ¿¡¼­ÀÇ ¸ðµç ÀÛ¾÷À» ¸¶Ãļ­ »ç¿ëÇϰí ÀÖ´Â mutex lock ÀÌ ´õÀÌ»ó ÇÊ¿ä ¾ø´Ù¸é pthread_mutex_unlock ¸¦ È£ÃâÇØ¼­ mtuex lock ¸¦ µÇµ¹·ÁÁØ´Ù.


3.4. pthread_mutex_unlock

int pthread_mutex_unlock(pthread_mutex_t *mutex); 
			
critical section ¿¡¼­ÀÇ ¸ðµç ÀÛ¾÷À» ¸¶Ä¡°í mutex lock À» µ¹·ÁÁÖ±â À§Çؼ­ »ç¿ëÇÑ´Ù. pthread_mutex_unlock ¸¦ ÀÌ¿ëÇØ¼­ mutex lock ¸¦ µÇµ¹·ÁÁÖ¸é ´Ù¸¥ ¾²·¹µå¿¡¼­ mutex lock ¸¦ ¾òÀ»¼ö ÀÖ´Â »óŰ¡ µÈ´Ù.


3.5. pthread_cond_init

int pthread_cond_init(pthread_cond_t *cond, 
                    const pthread_cond_attr *attr);
			
pthread_cond_init´Â Á¶°ßº¯¼ö (condition variable)cond¸¦ ÃʱâÈ­Çϱâ À§Çؼ­ »ç¿ëÇÑ´Ù. attr ¸¦ ÀÌ¿ëÇØ¼­ Á¶°Çº¯¼öÀÇ Æ¯¼ºÀ» º¯°æÇÒ¼ö ÀÖÀ¸¸ç, NULL À» ÁÙ°æ¿ì ±âº»Æ¯¼ºÀ¸·Î ÃʱâÈ­µÈ´Ù.

Á¶°Çº¯¼ö cond´Â »ó¼ö PTHREAD_COND_INITIALIZER À» ÀÌ¿ëÇØ¼­µµ ÃʱâÈ­ ÇÒ¼ö ÀÖ´Ù. Áï ´ÙÀ½°ú °°Àº 2°¡Áö ÃʱâÈ­ ¹æ¹ýÀÌ Á¸ÀçÇÑ´Ù.

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
or
pthread_cond_init(&cond, NULL);
			


3.6. pthread_cond_signal

int pthread_cond_signal(pthread_cond_t *cond);
			
Á¶°Çº¯¼ö cond¿¡ ½Ã±×³¯À» º¸³½´Ù. ½Ã±×³¯À» º¸³¾°æ¿ì cond¿¡¼­ ±â´Ù¸®´Â(wait) ¾²·¹µå°¡ ÀÖ´Ù¸é ¾²·¹µå¸¦ ±ú¿ì°Ô µÈ´Ù(ºÀ¼â°¡ Ç®¸²). ¸¸¾à Á¶°Çº¯¼ö cond¸¦ ±â´Ù¸®´Â ¾²·¹µå°¡ ¾ø´Ù¸é, ¾Æ¹«·± Àϵµ ÀϾÁö ¾Ê°ÔµÇ¸ç, ¿©·¯°³ÀÇ ¾²·¹µå°¡ ±â´Ù¸®°í ÀÖ´Ù¸é ±×Áß ÇϳªÀÇ ¾²·¹µå¿¡°Ô¸¸ Àü´ÞµÈ´Ù. À̶§ ¾î¶² ¾²·¹µå¿¡°Ô ½ÅÈ£°¡ Àü´ÞµÉÁö´Â ¾Ë¼ö ¾ø´Ù.


3.7. pthread_cond_boradcast

int pthread_cond_broadcast(pthread_cond_t *cond);
			
Á¶°Çº¯¼ö cond¿¡¼­ ±â´Ù¸®´Â(wait) ¸ðµç ¾²·¹µå¿¡°Ô ½ÅÈ£¸¦ º¸³»¼­, ±ú¿î´Ù´Â Á¡À» Á¦¿ÜÇϰí´Â pthread_cond_signal°ú µ¿ÀÏÇÏ°Ô ÀÛµ¿ÇÑ´Ù.


3.8. pthread_cond_wait

int pthread_cond_wait(pthread_cond_t cond, pthread_mutex_t *mutex); 
			
Á¶°Çº¯¼ö cond¸¦ ÅëÇØ¼­ ½ÅÈ£°¡ Àü´ÞµÉ¶§±îÁö ºí·°µÈ´Ù. ¸¸¾à ½ÅÈ£°¡ Àü´ÞµÇÁö ¾Ê´Â´Ù¸é ¿µ¿øÈ÷ ºí·°µÉ¼öµµ ÀÖ´Ù. pthread_cond_wait´Â ºí·°µÇ±â Àü¿¡ mutex Àá±ÝÀ» ÀÚµ¿À¸·Î µÇµ¹·ÁÁØ´Ù.


3.9. pthread_cond_timewait

int pthread_cond_timedwait(pthread_cont_t *cond, pthread_mutex_t *mutex, 
                           const struct timespec *abstime);
			
Á¶°Çº¯¼ö cond¸¦ ÅëÇØ¼­ ½ÅÈ£°¡ Àü´ÞµÉ¶§±îÁö ºí·°µÇ¸ç ÀÚµ¿À¸·Î mutexÀ» µ¹·ÁÁÖ´Â Á¡¿¡¼­´Â pthread_cond_wait¿Í µ¿ÀÏÇÏ´Ù. ±×·¯³ª ½Ã°£Ã¼Å©°¡ °¡´ÉÇØ¼­ abstime½Ã°£µ¿¾È ½ÅÈ£°¡ µµÂøÇÏÁö ¾Ê´Â´Ù¸é error ¸¦ ¹ß»ýÇϸ鼭 ¸®ÅÏÇÑ´Ù. À̶§ ¸®ÅϰªÀº ETIMEDOUT ÀÌ´Ù. errno °¡ ¼¼ÆÃµÇ´Â°Ô ¾Æ´Ñ, ¸®ÅϰªÀ¸·Î ¿¡·¯°¡ ³Ñ¾î¿À´Â°Í¿¡ ÁÖÀÇÇØ¾ß ÇÑ´Ù.

¶ÇÇÑ pthread_cond_timedwaitÇÔ¼ö´Â ´Ù¸¥ signal ¿¡ ÀÇÇØ¼­ interrupted µÉ¼ö ÀÖÀ¸¸ç À̶§ EINTR À» ¸®ÅÏÇÑ´Ù. ÀÌ ÇÔ¼ö¸¦ ¾µ¶§´Â interrupted »óȲ¿¡ ´ëÇÑ Ã³¸®¸¦ ÇØÁÖ¾î¾ß ÇÑ´Ù.


3.10. pthread_cond_destroy

int pthread_cond_destroy(pthread_cond_t *cond);
			
pthread_cond_init¸¦ ÅëÇØ¼­ »ý¼ºÇÑ Á¶°Çº¯¼öcond¿¡ ´ëÇÑ ÀÚ¿øÀ» ÇØÁ¦ÇÑ´Ù. destroy ÇÔ¼ö¸¦ È£ÃâÇϱâ Àü¿¡ ¾î¶² ¾²·¹µåµµ cond¿¡¼­ÀÇ ½Ã±×³ÎÀ» ±â´Ù¸®Áö ¾Ê´Â°É È®ÀÎÇØ¾ß ÇÑ´Ù. ¸¸¾à cond ½Ã±×³ÎÀ» ±â´Ù¸®´Â ¾²·¹µå°¡ Á¸ÀçÇÑ´Ù¸é ÀÌ ÇÔ¼ö´Â ½ÇÆÐÇϰí EBUSY ¸¦ ¸®ÅÏÇÑ´Ù.


3.11. ¿¹Á¦ÄÚµå

À̹øÀå¿¡¼­ ¼³¸íÇÑ ¾²·¹µå µ¿±âÈ­ °ü·Ã ÇÔ¼öÀÇ ÀÌÇØ¸¦ µ½±â À§Çؼ­ °£´ÜÇÑ ¿¹Á¦¸¦ ÁغñÇß´Ù. ¼³¸íÀº ÁÖ¼®À¸·Î ´ë½ÅÇÑ´Ù.

¿¹Á¦ : pthrad_sync_api.c

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iostream>

using namespace std;

void *ping(void *);
void *pong(void *);

pthread_mutex_t sync_mutex;
pthread_cond_t  sync_cond;

pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  gcond  = PTHREAD_COND_INITIALIZER;

int main()
{
    vector<void *(*)(void *)> thread_list;
    vector<pthread_t> tident(10); 
    int thresult;
    int status;
    int i;

    pthread_mutex_init(&sync_mutex, NULL);
    pthread_cond_init(&sync_cond, NULL);

    thread_list.push_back(pong);
    thread_list.push_back(ping);

    for(i = 0; i < thread_list.size(); i++ )
    {
        pthread_mutex_lock(&sync_mutex);
        if (pthread_create(&tident[i], NULL, thread_list[i], (void *)NULL) <0)
        {
            perror("error:");
            exit(0);
        }
        pthread_cond_wait(&sync_cond, &sync_mutex);
        pthread_mutex_unlock(&sync_mutex);
    }
    for (i = 0; i < tident.size(); i++)
    {
        pthread_join(tident[i], (void **)&status);
    }
}

void *ping(void *data)
{
    int i=0;
    pthread_mutex_lock(&sync_mutex);
    pthread_cond_signal(&sync_cond);
    pthread_mutex_unlock(&sync_mutex);
    while(1)
    {
        pthread_mutex_lock(&gmutex);
        printf("%d : ping\n", i);
        pthread_cond_signal(&gcond);
        pthread_cond_wait(&gcond, &gmutex);
        pthread_mutex_unlock(&gmutex);
        usleep(random()%100);
        i++;
    }
}

void *pong(void *data)
{
    int i = 0;
    pthread_mutex_lock(&sync_mutex);
    sleep(1);
    pthread_cond_signal(&sync_cond);
    pthread_mutex_unlock(&sync_mutex);
    while(1)
    {
        pthread_mutex_lock(&gmutex);
        pthread_cond_wait(&gcond, &gmutex);
        printf("%d : pong\n", i);
        pthread_cond_signal(&gcond);
        pthread_mutex_unlock(&gmutex);
        i++;
    }
}
			

À§ÀÇ ¿¹Á¦´Â ping&pong ÇÁ·Î±×·¥À¸·Î ping ¾²·¹µå¿Í pong ¾²·¹µå°¡ °¢°¢ ¹ø°¥¾Æ°¡¸é¼­ "ping", "pong" À» ³¯¸®´Â ÇÁ·Î±×·¥ÀÌ´Ù. 2°³ÀÇ ¿µ¿ª¿¡ °ÉÃļ­ Å©¸®Æ¼Äü½¼ÇÀÌ ÁöÁ¤µÇ¾î ÀÖÀ¸¸ç °¢ Å©¸®Æ¼Äü½¼Ç¾È¿¡´Â ¾²·¹µå µ¿±âÈ­¸¦ À§Çؼ­ ptread_cond_signal ÀÌ ¾²¿©Áö°í ÀÖ´Ù.

À§ÀÇ ÄÚµå´Â ±âº»ÀûÀ¸·Î pong ¾²·¹µå°¡ ¸ÕÀú ½Ã±×³ÎÀ» ´ë±âÇϰí ÀÖ´Ù°¡ ±× ÈÄ ping ¾²·¹µå°¡ ÁøÀÔÇØ¼­ "ping"À» ³¯¸®°í ½Ã±×³ÎÀ» ¹ß»ý½Ã۸é "pong" ¸Þ½ÃÁö¸¦ ¹ß»ý½Ã۵µ·Ï µÇ¾î ÀÖ´Ù. ±×·¸´Ù¸é while ¹®¿¡ ÀÖ´Â Å©¸®Æ¼Äà ¼½¼Ç¿¡ ¹Ýµå½Ã pong ¾²·¹µå°¡ ¸ÕÀú ÁøÀÔÇÒ¼ö ÀÖµµ·Ï ¸¸µé¾îÁà¾ß ÇÒ°ÍÀÌ´Ù. ±×·¡¼­ À§ÀÇ Äڵ忡¼­´Â pong ¾²·¹µå¸¦ ¸ÕÀú »ý¼º½ÃÄ×´Ù. ±×·¯³ª À̰͸¸À¸·Î´Â ÃæºÐÇÏÁö ¾Ê´Ù. ¿¹¸¦µé¾î¼­ pong ¾²·¹µå¿¡¼­ Å©¸®Æ¼Äü½¼Ç¿¡ µé¾î°¡±â À§Çؼ­ ¾î¶² ºÎ°¡ÀûÀÎ ÀÛ¾÷ÀÌ ÀÖ´Ù°í ÇßÀ»¶§(¸Þ¸ð¸®ÃʱâÈ­, ±âŸ ´Ù¸¥ ÇÔ¼ö È£Ãâ°ú °°Àº, À§¿¡¼­´Â sleep À¸·Î ´ë½ÅÇß´Ù), ¿ì¸®°¡ ÀǵµÇß´ø ¹Ù¿Í´Â ´Ù¸£°Ô ping °¡ ¸ÕÀú Å©¸®Æ¼Äü½¼Ç¿¡ ÁøÀÔÇÒ¼öµµ ÀÖ´Ù. ÀÌ·²°æ¿ì 2°³ÀÇ ¾²·¹µå´Â ±³Âø»óÅ¿¡ ºüÁö°Ô µÈ´Ù.

ping ¾²·¹µå°¡ Å©¸®Æ¼Äü½¼Ç¿¡ ¸ÕÀú ÁøÀÔÇßÀ»°æ¿ì ping ¾²·¹µå´Â "ping" Ãâ·Â½ÃŰ°í ½Ã±×³ÎÀ» ¹ß»ý½Ãų °ÍÀ̰í pong ¾²·¹µå°¡ "pong"¸¦ Ãâ·Â½ÃŰ°í ½Ã±×³ÎÀ» ¹ß»ý½Ãų¶§±îÁö ½Ã±×³Î´ë±â ÇÏ°Ô µÈ´Ù. ping ¾²·¹µå°¡ ½Ã±×³Î´ë±â ÇÏ°Ô µÇ¸é, Å©¸®Æ¼Äü½¼Ç¿¡ ´ëÇÑ ¹ÂÅØ½º Àá±ÝÀÌ ÇØÁ¦µÊÀ¸·Î µÚ´Ê°Ô Å©¸®Æ¼Äü½¼Å³× ÁøÀÔÀ» ½ÃµµÇÏ´ø pong °¡ Å©¸®Æ¼Äü½¼Ç¿¡ ÁøÀÔÇϰí ping ¾²·¹µå¿¡¼­ºÎÅÍ ½ÅÈ£°¡ ÀÖ´ÂÁö ±â´Ù¸®°Ô µÉ°ÍÀÌ´Ù. ±×·¯³ª ping ¾²·¹µå´Â ÀÌ¹Ì ½ÅÈ£¸¦ ³¯·Á¹ö·ÈÀ½À¸·Î, pong ¾²·¹µå´Â °áÄÚ µµÂøÇÏÁö ¾ÊÀ» ½ÅÈ£¸¦ ±â´Ù¸®¸ç ¿µ¿øÈ÷ ½Ã±×³Î´ë±â ÇÏ°Ô µÉ°ÍÀÌ´Ù. ÀÌ·±½ÄÀ¸·Î 2°³ÀÇ ¾²·¹µå´Â ±³Âø»óÅ¿¡ ºüÁ® ¹ö¸°´Ù.

ÀÌ ¹®Á¦´Â ¾²·¹µå°£ µ¿±âÈ­¸¦ ÀÌ¿ëÇØ¼­ ÇØ°áÇÒ¼ö ÀÖÀ¸¸ç, À§ Äڵ忡¼­´Â mutex Àá±Ý°ú, Á¶°Çº¯¼ö¸¦ ÀÌ¿ëÇØ¼­ ÇØ°áÇϰí ÀÖ´Ù. ¹°·Ð ¾²·¹µå°£ µ¿±âÈ­¸¦ À§Çؼ­ »ç¿ëÇÒ¼ö ÀÖ´Â ¿ø½Ã?ÀûÀÎ ¹æ¹ýÀ¸·Î sleep ³ª usleep °°Àº ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ¹æ¹ýµµ ÀÖ±ä ÇÏÁö¸¸, ping ¾²·¹µå¿¡¼­ Å©¸®Æ¼Äà ¼½¼Ç¿¡ ÁøÀÔÇϱâÀü 1ÃÊ Á¤µµ sleep À» ÁÖ´Â ½ÄÀ¸·Î »ç¿ë°¡´ÉÇÏÁö¸¸ ÃßõÇÒ¸¸ÇÏÁø ¾Ê´Ù. (°£È¤ °£´ÜÇÏ°Ô »ç¿ëÇÒ¼ö´Â À¸¸ç, °¡Àå È®½ÇÇÑ ¹æ¹ýÀ» Á¦°øÇØ Áֱ⵵ ÇÑ´Ù)


4. Thread Attribute ÇÔ¼ö

4.1. pthread_attr_init

int pthread_attr_init(pthread_attr_t *attr);
			
pthread_attr_init´Â thread attribute °´Ã¼ÀÎ attrÀ» µðÆúÆ® °ªÀ¸·Î ÃʱâÈ­ ½ÃŲ´Ù.

¼º°øÇÒ°æ¿ì 0À» µ¹·ÁÁÖ°í ½ÇÆÐÇÒ°æ¿ì -1 À» µÇµ¹·ÁÁØ´Ù.


4.2. pthread_attr_distroy

int pthread_attr_destroy(pthread_attr_t *attr);
			
pthread_attr_init¿¡ ÀÇÇØ »ý¼ºµÈ thread attribute °´Ã¼ÀÎ attrÀ» Á¦°ÅÇÑ´Ù. Á¦°ÅµÈ attr À» ´Ù½Ã »ç¿ëÇϱâ À§Çؼ­´Â pthread_attr_init¸¦ ÀÌ¿ëÇØ¼­ ´Ù½Ã ÃʱâÈ­ ÇØÁÖ¾î¾ß ÇÑ´Ù.


4.3. pthread_attr_getscope

int pthread_attr_getscope(const pthread_attr_t *attr, 
             int *scope);
			
¾²·¹µå°¡ ¾î¶² ¿µ¿ª(scope)¿¡¼­ ´Ù·ç¾îÁö°í ÀÖ´ÂÁö¸¦ ¾ò¾î¿À±â À§Çؼ­ »ç¿ëµÈ´Ù. PTHREAD_SCOPE_SYSTEM°ú PTHREAD_SCOPE_PROCESS ÀÇ 2°¡Áö ¿µ¿ªÁß¿¡ ¼±ÅÃÇÒ¼ö ÀÖ´Ù. SYSTEM ¿µ¿ª ¾²·¹µå´Â user ¸ðµå ¾²·¹µå¶ó°í ºÒ¸®¿ì¸ç, PROCESS ¾²·¹µå´Â Ä¿³Î¸ðµå ¾²·¹µå¶ó°í ºÒ¸®¿î´Ù. ¸®´ª½ºÀÇ °æ¿ì À¯Àú¸ðµå ¾²·¹µåÀε¥, Áï Ä¿³Î¿¡¼­ ¾²·¹µå¸¦ ½ºÄÉÁ층ÇÏ´Â ¹æ½ÄÀÌ ¾Æ´Ñ ¾²·¹µå ¶óÀ̺귯¸®¸¦ ÅëÇØ¼­ ¾²·¹µå¸¦ ½ºÄÉÁ층 ÇÏ´Â ¹æ½ÄÀ» »ç¿ëÇÑ´Ù.

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>


int main()
{
    pthread_attr_t pattr;
    int scope;

    pthread_attr_init(&pattr);

    pthread_attr_getscope(&pattr, &scope);
    if (scope == PTHREAD_SCOPE_SYSTEM)
    {
        printf("user mode thread\n");
    }
    else if (scope ==  PTHREAD_SCOPE_PROCESS)
    {
        printf("Kernel mode thread\n");
    }

    return 1;
}
			
À§ ÇÁ·Î±×·¥À» ÄÄÆÄÀÏÇÑÈÄ Linux ¿¡¼­ ½ÇÇà½Ã۸é "user mode thread"¸¦ Ãâ·ÂÇÏ°í ¼Ö¶ó¸®½º »ó¿¡¼­ ½ÇÇà½Ã۸é "kernel mode thread"¸¦ Ãâ·ÂÇÑ´Ù.


4.4. pthread_attr_setscope

int pthread_attr_setscope(pthread_attr_t *attr, int scope);
			
¾²·¹µå°¡ ¾î¶² ¿µ¿ª(scope)¿¡¼­ ÀÛµ¿ÇÏ°Ô ÇÒ°ÍÀÎÁö °áÁ¤Çϱâ À§Çؼ­ »ç¿ëÇÑ´Ù. ¸®´ª½ºÀÇ °æ¿ì Kernel mode ¾²·¹µå¸¦ Áö¿øÇÏÁö ¾ÊÀ½À¸·Î ¿ÀÁ÷ PTHREAD_SCOPE_SYSTEM ¸¸À» ¼±ÅÃÇÒ¼ö ÀÖ´Ù. ¹Ý¸é ¼Ö¶ó¸®½º´Â À¯Àú¸ðµå¿Í Ä¿³Î¸ðµåÁß ¼±ÅÃÀÌ °¡´ÉÇÏ´Ù.

pthread_attr_setscope.c

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>


int main()
{
    pthread_attr_t pattr;
    int scope;

    pthread_attr_init(&pattr);

    pthread_attr_setscope(&pattr, PTHREAD_SCOPE_PROCESS);
    pthread_attr_getscope(&pattr, &scope);
    if (scope == PTHREAD_SCOPE_SYSTEM)
    {
        printf("user mode thread\n");
    }
    else if (scope ==  PTHREAD_SCOPE_PROCESS)
    {
        printf("Kernel mode thread\n");
    }

    return 1;
}
			
À§Äڵ忡¼­ ¾²·¹µå°¡ Ä¿³Î ¸ðµå¿¡¼­ ÀÛµ¿Çϵµ·Ï ÁöÁ¤À» Çß´Ù. ¸®´ª½º¿¡¼­ ½ÇÇà½Ãų°æ¿ì¿¡´Â ºñ·Ï Ä¿³Î¸ðµå·Î ÁöÁ¤À» Çß´Ù°í ÇÏ´õ¶óµµ À¯Àú¸ðµå ¾²·¹µå·Î ÀÛµ¿ÇÏ°Ô µÈ´Ù. ¼Ö¶ó¸®½ºÀÇ °æ¿ì¿¡´Â setscope ·Î ÁöÁ¤ÇÑ´ë·Î Ä¿³Î¸ðµå¿¡¼­ ÀÛµ¿ÇÏ°Ô µÈ´Ù.


4.5. pthread_attr_getdetachstate

int pthread_attr_getdetachstate(pthread_attr_t *attr,
           int detachstate);
			
¾²·¹µå°¡ join °¡´ÉÇÑ »óÅÂ(PTHREAD_CREATE_JOINABLE) ÀÎÁö detached »óÅÂÀÎÁö (PTHREAD_CREATE_DETACHED) ÀÎÁö¸¦ ¾Ë¾Æ³½´Ù. ¾Ë¾Æ³½ °ªÀº ¾Æ±Ô¸ÕÆ® detachstate ¿¡ ÀúÀåµÈ´Ù.

±âº»Àº PTHREAD_CREATE_JOINABLE À̸ç, pthread_detach¸¦ ÀÌ¿ëÇØ¼­ »ý¼ºµÈ ¾²·¹µå¸¦ detach »óÅ·Π¸¸µé¾úÀ»°æ¿ì ¶Ç´Â pthread_attr_setdetachstateÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ¾²·¹µå¸¦ detache »óÅ·Πº¯°æ½ÃÄ×À»°æ¿ì PTHREAD_CREATE_DETACHED »óŰ¡ µÈ´Ù.

¿¹Á¦ : pthread_attr_getdetachstate.c

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>

pthread_attr_t attr;
void *test(void *a)
{
    int policy;
    printf("Thread Create\n");
    pthread_attr_getdetachstate(&attr, &policy);
    if (policy == PTHREAD_CREATE_JOINABLE)
    {
        printf ("Join able\n");
    }
    else if (policy == PTHREAD_CREATE_DETACHED)
    {
        printf ("Detache\n");
    }
}
int main()
{
    int status;
    pthread_t p_thread;
    pthread_attr_init(&attr);
    if (pthread_create(&p_thread, NULL, test, (void *)NULL) < 0)
    {
        exit(0);
    }

    pthread_join(p_thread, (void **)&status);
}
			
À§ÀÇ ÇÁ·Î±×·¥À» ½ÇÇà½ÃŰ¸é ºÐ¸í "Join able"¸¦ Ãâ·ÂÇÒ°ÍÀÌ´Ù.


4.6. pthread_attr_setdetachstate

int  pthread_attr_setdetachstate(pthread_attr_t *attr, 
             int detachstate);
			
¾²·¹µåÀÇ »óŸ¦ PTHREAD_CREATE_JOINABLE ȤÀº PTHREAD_CREATE_DETACHED »óÅ·Πº¯°æ½Ã۱â À§Çؼ­ »ç¿ëµÈ´Ù. ¾Æ·¡¿Í °°Àº ¹æ¹ýÀ¸·Î »ç¿ëÇÏ¸é µÈ´Ù.
pthread_attr_t attr;
...
// JOINABLE »óÅ·Πº¯°æÇϰíÀÚ ÇÒ¶§ 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// DETACHED »óÅ·Πº¯°æÇϰíÀÚ ÇÒ¶§
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
			


5. ¾²·¹µå ½Ã±×³Î °ü·Ã

¾²·¹µå°£ ÇÁ·Î¼¼½º¿Í ¾²·¹µå°£ ½Ã±×³Î Àü´Þ°ü·Ã APIµéÀÌ´Ù. ÀÚ¼¼ÇÑ ³»¿ëÀº ¾²·¹µå¿Í ½Ã±×³ÎÀ» Âü°íÇϱ⠹ٶõ´Ù.


5.1. pthread_sigmask

#include <pthread.h>
#include <signal.h>

int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask);
			
¾²·¹µå¿¡¼­ ½Ã±×³ÎÀº ¼­·Î °øÀ¯µÈ´Ù. ±×·±ÀÌÀ¯·Î ¸¸¾à ÇÁ·Î¼¼½º¿¡ ½Ã±×³ÎÀÌ Àü´ÞµÇ¸é ÇÁ·Î¼¼½º°¡ »ý¼ºµÈ ¸ðµç ¾²·¹µå·Î ½Ã±×³ÎÀÌ Àü´ÞµÈ´Ù. ±×·¯³ª ƯÁ¤ ¾²·¹µå¸¸ ½Ã±×³ÎÀ» ¹Þµµ·Ï ÇÏ°í ½ÍÀ» ¶§°¡ ÀÖÀ» °ÍÀÌ´Ù. À̰æ¿ì ÀÌ ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¸é µÈ´Ù.


5.2. pthread_kill

#include <pthread.h>
#include <signal.h>

int pthread_kill(pthread_t thread, int signo);
			
¾²·¹µå ½Äº°¹øÈ£ thread·Î signo ¹øÈ£ÀÇ ½Ã±×³ÎÀ» Àü´ÞÇÑ´Ù.


5.3. sigwait

#include <pthread.h>
#include >signal.h>

int sigwait(const sigset_t *set, int *sig);
			
½Ã±×³Î Àü´ÞÀ» µ¿±âÀûÀ¸·Î ±â´Ù¸°´Ù.


6. ¾²·¹µå Ãë¼Ò

ÀÚ¼¼ÇÑ ³»¿ëÀº ¾²·¹µå Ãë¼Ò¿Í Á¾·á¿Í pthread_cancel(3)À» Âü°íÇϱ⠹ٶõ´Ù. ¿©±â¿¡¼­´Â À妽º¸¸ Á¦°øÇÑ´Ù.


6.1. pthread_cancel

#include <pthread.h>

int pthread_cancel(pthread_t thread);
			


6.2. pthread_setcancelstate

#include <pthread.h>

int pthread_setcancelstate(int state, int *oldstate);
			


6.3. pthread_setcancelstate

#include <pthread.h>

int pthread_setcancelstate(int state, int *oldstate);
			


6.4. pthread_setcanceltype

#include <pthread.h>

int pthread_setcanceltype(int type, int *oldtype);
			


6.5. pthread_testcancel

#include <pthread.h>

void pthread_testcancel(void);