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 |