Korea FreeBSD Users Group
Korea FreeBSD Users Group News, Internal, Projects, Home
Software, Support, Documentation

(Answer) (Category) FreeBSD ºñ°ø½Ä Çѱ¹¾î FAQ : (Category) ÇÁ·Î±×·¡¹Ö :
FreeBSD¿¡¼­ thread¸¦ »ç¿ëÇÏ°í ½Í¾î¿ä.
FreeBSD¿¡¼­´Â POSIX pthread(IEEE Std 1003.1c-1995)¸¦ Áö¿øÇÏ°í ÀÖ½À´Ï´Ù.

´ÙÀ½Àº ¾²·¹µå¸¦ »ý¼ºÇÏ°í µ¿±âÈ­ ÇÏ´Â °£´ÜÇÑ ¿¹ÀÔ´Ï´Ù.

thrtest.cÀÇ ³»¿ë
-----------------------¿©±â¼­ºÎÅÍ----------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
#include <limits.h>
 
#include <errno.h>
 
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t condlock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int     counter = 0;
 
static void *
child(void *_arg)
{
        int i;
 
        i = (int)_arg;
        printf("child %d spawned\n", i);
        pthread_mutex_lock(&condlock);
        counter++;
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&condlock);
        pthread_mutex_lock(&lock);
        printf("child %d done\n", i);
        pthread_mutex_unlock(&lock);
 
        return NULL;
}
 
int
main(int argc, char *argv[])
{
        int             i, ret;
        int             nchildren;
        size_t  stacksize;
 
        pthread_t child_thread;
        pthread_attr_t  attr;
 
        pthread_attr_init(&attr);
 
        if (2 == argc) {
                printf("use default stacksize\n");
        }
        else if (3 == argc) {
                stacksize = strtoul(argv[2], (char **)NULL, 10);
                if (!pthread_attr_setstacksize(&attr, stacksize*1024)) {
                        printf("set stacksize = %dKB\n", stacksize);
                }
        }
        else {
                printf("usage: thrtest <#children> [stacksize(kb)]\n");
                return 1;
        }
 
        nchildren = strtol(argv[1], (char **)NULL, 10);
 
 
        if (!pthread_attr_getstacksize(&attr, &stacksize)) {
                printf("stack size = %d\n", stacksize);
        }
        printf("PTHREAD_THREAD_MAX in limits.h is %u\n", PTHREAD_THREADS_MAX);
 
        pthread_mutex_lock(&lock);
 
        for (i = 0; i < nchildren; i++) {
                if (ret = pthread_create(&child_thread, &attr, (void *(*)(void *
))child, (void *)i)) {
                        printf("Test failed : %s (%d)\n", strerror(ret), i);
                        exit(0);
                }
        }
        pthread_mutex_lock(&condlock);
        while (counter < nchildren) {
                pthread_cond_wait(&cond, &condlock);
        }
        pthread_mutex_unlock(&condlock);
 
        printf("all spawned\n");
        pthread_mutex_unlock(&lock);
 
        for (i = 0; i < nchildren; i++) {
                pthread_join(child_thread, NULL);
        }
 
        pthread_mutex_destroy(&lock);
        pthread_mutex_destroy(&condlock);
        pthread_cond_destroy(&cond);
        pthread_attr_destroy(&attr);
        return (0);
}
------------------------¿©±â±îÁö-----------------------

gcc -pthread -D_THREAD)SAFE -o thrtest thrtest.c
¿Í °°ÀÌ ÇÏ¿© ÄÄÆÄÀÏÇÕ´Ï´Ù.

./thrtest 10
°ú °°ÀÌ ÇÏ¿© ¾²·¹µå°¡ »ý¼ºµÇ°í ¼öÇàµÇ´Â °ÍÀ» È®ÀÎÇÒ ¼ö ÀÖ½À´Ï´Ù.

pthread API´Â man pthread¸¦ ÇÏ¸é º¼ ¼ö ÀÖ½À´Ï´Ù.
sonnet
FreeBSD ports¿¡´Â GNU pth¶ó´Â °ÍÀÌ ÀÖ½À´Ï´Ù. ÀÌ°ÍÀº À¯Àú ¶óÀ̺귯¸® ¾²·¹
µåÀÇ ÀÏÁ¾À¸·Î FreeBSD ÀÌ¿ÜÀÇ ´Ù¸¥ ¿©·¯ unix¿¡¼­µµ Àß µ¿À۵˴ϴÙ. ÀÀ´ä¼º
°³¼±À» À§ÇÑ ¸ñÀû¿¡¼­ ¾²·¹µå¸¦ »ç¿ëÇÒ »ý°¢À̶ó¸é ÀÌ¿Í °°Àº non-preemptive
thread¸¦ »ç¿ëÇÏ´Â °Íµµ ÇÑ°¡Áö ¹æ¹ýÀÔ´Ï´Ù.

»ç¿ë¹ýÀº ´ÙÀ½°ú °°½À´Ï´Ù.

cd /usr/ports/devel/pth;make;make installÇؼ­ pth¸¦ ¼³Ä¡ÇÕ´Ï´Ù.

´ÙÀ½Àº ¾²·¹µå¸¦ »ý¼ºÇÏ°í µ¿±âÈ­ ÇÏ´Â °£´ÜÇÑ ¿¹ÀÔ´Ï´Ù.

pthtest.cÀÇ ³»¿ë
-----------------------¿©±â¼­ºÎÅÍ----------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pth.h>
 
#include <errno.h>
 
pth_mutex_t lock = PTH_MUTEX_INIT;
pth_mutex_t condlock = PTH_MUTEX_INIT;
pth_cond_t cond = PTH_COND_INIT;
int     counter = 0;
int     nchildren;
 
static void *
child(void *_arg)
{
        int     i;
 
        i = (int)_arg;
        printf("child %d spawned\n", i);
        pth_mutex_acquire(&condlock, FALSE, NULL);
        counter++;
        if (counter == nchildren)
                pth_cond_notify(&cond, FALSE);
        pth_mutex_release(&condlock);
        pth_mutex_acquire(&lock, FALSE, NULL);
        printf("child %d done\n", i);
        pth_mutex_release(&lock);
 
        return NULL;
}
 
int
main(int argc, char *argv[])
{
        int             i;
        size_t  stacksize = 64;
        pth_attr_t      attr;
 
        if (2 == argc) {
                printf("use default stacksize = %dKB\n", stacksize);
        }
        else if (3 == argc) {
                stacksize = strtol(argv[2], (char **)NULL, 10);
                printf("set stacksize = %dKB\n", stacksize);
        }
        else {
                printf("usage: pthtest <#children> [stacksize(kb)]\n");
                return 1;
        }
 
        nchildren = strtol(argv[1], (char **)NULL, 10);
 
        pth_init();
        attr = pth_attr_new();
        pth_attr_set(attr, PTH_ATTR_NAME, "child");
        pth_attr_set(attr, PTH_ATTR_STACK_SIZE, stacksize*1024);
        pth_attr_set(attr, PTH_ATTR_JOINABLE, TRUE);
 
        pth_mutex_acquire(&lock, FALSE, NULL);
 
        for (i = 0; i < nchildren; i++) {
                if(!pth_spawn(attr, (void *(*)(void *))child, (void *)i)) {
                        printf("Test failed (%d)\n", i);
                        exit(0);
                }
        }
 
        pth_mutex_acquire(&condlock, FALSE, NULL);
        while (counter < nchildren) {
                printf("counter = %d\n", counter);
                pth_cond_await(&cond, &condlock, NULL);
        }
        pth_mutex_release(&condlock);
 
        printf("all spawned\n");
        pth_mutex_release(&lock);
 
        for (i = 0; i < nchildren; i++) {
                pth_join(NULL, NULL);
        }
 
        return (0);
}
------------------------¿©±â±îÁö-----------------------

gcc `pth-config --cflags` -c pthtest.c
gcc `pth-config --ldflags` -o pthtest pthtest.o `pth-config --libs`

./pthtest 10°ú °°ÀÌ ÇÏ¿© ¾²·¹µå°¡ »ý¼ºµÇ°í ¼öÇàµÇ´Â °ÍÀ» È®ÀÎÇÒ ¼ö ÀÖ½À
´Ï´Ù. 
pth API´Â man pthÇÏ¸é º¼ ¼ö ÀÖ½À´Ï´Ù.
sonnet
[Append to This Answer]
Previous: (Answer) °øÀ¯ ¶óÀ̺귯¸®¸¦ ¾î¶»°Ô ¸¸µéÁÒ?
This document is: http://www.kr.freebsd.org/cgi-bin/fom.cgi?file=78
[Search] [Appearance]
This is a Faq-O-Matic 2.719.

Copyright © 1998-2003 Korea FreeBSD Users Group.
All rights reserved. webmaster at kr.FreeBSD.org
Powered by FreeBSD