Skip to content

Instantly share code, notes, and snippets.

@dchiji
Created December 23, 2009 10:40
Show Gist options
  • Save dchiji/262457 to your computer and use it in GitHub Desktop.
Save dchiji/262457 to your computer and use it in GitHub Desktop.
thread pool
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
typedef struct tid {
int n;
pthread_t *thread;
} tid_t;
typedef struct flag {
void *(*func)(void *);
void *param;
} flag_t;
int max;
flag_t **flags; // flags[スレッドID]に関数ポインタが入っていれば,そのプロセスが関数を実行する
tid_t **queue; // 暇なスレッド
int head;
int tail;
void *loop(void *param)
{
int boolean;
tid_t *self = (tid_t *)param;
int n = self->n;
flag_t *flag;
int _tail;
pthread_detach(*(self->thread));
while(1) {
if(flags[n] != (flag_t *)0) {
flag = flags[n];
flags[n] = 0;
(flag->func)(flag->param);
free(flag);
// tailを動かす
do {
_tail = tail;
if(tail == max - 1) {
boolean = __sync_bool_compare_and_swap(&tail, _tail, 0);
} else {
boolean = __sync_bool_compare_and_swap(&tail, _tail, _tail + 1);
}
} while(!boolean);
queue[_tail + 1] = self;
}
}
}
int tp_init(int m)
{
int i;
max = m;
flags = (flag_t **)malloc(sizeof(flag_t *) * m);
queue = (tid_t **)malloc(sizeof(int) * m);
head = 0;
tail = m - 1;
for(i = 0; i < m; i++) {
tid_t *p = (tid_t *)malloc(sizeof(tid_t));
pthread_t *thread = (pthread_t *)malloc(sizeof(pthread_t));
p->n = i;
p->thread = thread;
if(pthread_create(thread, NULL, loop, (void *)p) != 0) {
perror("pthread_create()");
return 0;
}
flags[i] = 0;
queue[i] = p;
}
return 1;
}
int tp_create(void *(*func)(void *), void *param)
{
flag_t *flag = (flag_t *)malloc(sizeof(flag_t));
tid_t *p = queue[head];
int free_thread_n = p->n;
head++;
// TODO: head == tailだったときの処理
flag->func = func;
flag->param = param;
flags[free_thread_n] = flag;
return 1;
}
void *test(void *param)
{
printf("hello, world\n");
return NULL;
}
int main()
{
tp_init(30);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
tp_create(test, NULL);
sleep(3);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment