自分ででたらめに書いたスレッドプール

10425 ワード

昨日ラインオフプールを見て、原理は何でも分かりやすいですが、実現するには自分のやり方がとても不器用だと感じました.ここでは直接タスクもプールにしていないので、動的な割り当て操作は必要ありません.コードとテストは次のとおりです.
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define MAX_THREAD_NUM 100
#define MAX_WORK_NUM 1000

struct gwork{
void (*func)(void *arg);
void *arg;
int next;
};


struct gthread_pool{
pthread_t threads[MAX_THREAD_NUM]; //threads.
pthread_mutex_t glock;

gwork works[MAX_WORK_NUM]; //works.
int free_head;
int wait_head;
int flags;
int running;
};

void list_add(int item, int *head, gthread_pool *pool);
int list_delete(int *head, gthread_pool *pool);

void* gwork_func(void *arg){
int item;
gthread_pool *pool = (gthread_pool*)arg;
while(true){
if(pool->wait_head == -1){
continue;
}else{
pthread_mutex_lock(&(pool->glock));
if(pool->wait_head != -1){
item = list_delete(&pool->wait_head, pool);
pool->running++;
}
pthread_mutex_unlock(&(pool->glock));

printf("work %d is running.
", item);

// begin running.
(pool->works[item].func)(pool->works[item].arg);

printf("work %d has finished.
", item);

pthread_mutex_lock(&(pool->glock));
list_add(item, &pool->free_head, pool);
pool->running--;
pthread_mutex_unlock(&(pool->glock));
}
}
}

// add an item from list.
inline void list_add(int item, int *head, gthread_pool* pool){
if(pool == NULL || item < 0)
return;

pool->works[item].next = *head;
*head = item;
}

// delete an item from list.
inline int list_delete(int *head, gthread_pool* pool){
int item = *head;
*head = pool->works[*head].next;
return item;
}


gthread_pool* gthread_pool_create(){
int i;

gthread_pool *pool = (gthread_pool*)malloc(sizeof(struct gthread_pool));
if(pool == NULL)
return NULL;

memset(pool->works, 0, sizeof(pool->works));
for(i = 0; i < MAX_WORK_NUM; i++){
pool->works[i].next = i-1;
}
pool->free_head = MAX_WORK_NUM-1;
pool->wait_head = -1;
pool->running = 0;

for(i = 0; i < MAX_THREAD_NUM; i++){
if(pthread_create(&(pool->threads[i]), NULL, gwork_func, (void*)pool)){
printf("create thread[%d] fail.
", i);
free(pool);
return NULL;
}
}

pool->flags = 0; //running.
printf("creat pool success.
");
return pool;
}

int gthread_pool_add(gthread_pool* pool, gwork work){
int item = -1;
if(pool->free_head == -1){
printf("faild to insert a work.
");
return -1;
}
pthread_mutex_lock(&(pool->glock));
if(pool->free_head >= 0 && pool->flags == 0){
item = list_delete(&pool->free_head, pool);
list_add(item, &pool->wait_head, pool);
pool->works[item].func = work.func;
pool->works[item].arg = work.arg;
}else{
printf("faild to insert a work.
");
}
pthread_mutex_unlock(&(pool->glock));
return item;
}

int gthread_pool_destroy(gthread_pool* pool){
pool->flags = 1; //stoped.

// wait for all things have been done.
while(pool->running > 0){
sleep(1);
}
free(pool);
printf("gthread_pool_destroy success.
");

return 0;
}

次はテスト用のコードです.
#include "thread_pool.h"

gthread_pool *pool;

void work_func(void *arg){
pthread_t tid = pthread_self();

int second = (int)arg;
sleep(second);
printf("%u
", (unsigned)tid);
}

int main(){
gwork work;
int i = 0;
pool = gthread_pool_create();

for(i=0; i < 10; i++){
work.func = work_func;
work.arg = (void*)i;
gthread_pool_add(pool, work);
sleep(1);
}

gthread_pool_destroy(pool);
return 0;
}

このやり方はあまりにも愚かで、他の人がどのようにしたのかを見て、数日後にもう一度書き直します.
--------------------------------------
レンガを撮ってください.