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 |