一个简单的线程池和队列的搭配使用
thread_pool.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "queue.h"
#define POOL_NUM 2
typedef struct _thread_pool
{
pthread_t *tid;
queue_t *task;
pthread_mutex_t lock;
pthread_cond_t cond;
//int count;
} thread_pool;
int g_flag = 0;
void *worker(void *arg)
{
int *ret;
thread_pool *pool = (thread_pool *) arg;
while(1)
{
pthread_mutex_lock(&pool->lock);
while(queue_isempty(pool->task))
{
pthread_cond_wait(&pool->cond, &pool->lock);
}
pthread_mutex_unlock(&pool->lock);
printf("i am work, tid:%ld.\n", pthread_self());
ret = queue_dequeue(pool->task);
printf("dequeue element:%d.\n", *ret);
}
return ((void *) 1);
}
thread_pool *create_thread_pool(int size)
{
int i;
thread_pool *pool;
pool = (thread_pool *)malloc(sizeof(struct _thread_pool));
if (pool == NULL)
{
return NULL;
}
pool->tid = (pthread_t *)malloc(sizeof(pthread_t) * size);
if (pool->tid == NULL)
{
return NULL;
}
pthread_mutex_init(&pool->lock, NULL);
pthread_cond_init(&pool->cond, NULL);
pool->task = queue_init();
for (i = 0; i < size; i++)
{
pthread_create(pool->tid+i, NULL, worker, (void *)pool);
}
return pool;
}
void *add_task(void *arg)
{
int *element;
printf("create thread, tid:%ld.\n", pthread_self());
thread_pool *pool = (thread_pool *)arg;
int i;
for (i = 0; i < 3; i++)
{
sleep(1);
element = queue_enqueue(pool->task, sizeof(unsigned int));
*element = i + 'A';
pthread_cond_signal(&pool->cond);
}
return ((void *)0);
}
int main(int argc, char *argv[])
{
pthread_t tid;
thread_pool *pool;
int ret;
pool = create_thread_pool(POOL_NUM);
if (pool == NULL)
return 0;
printf("create pthread pool success.\n");
pthread_create(&tid, NULL, add_task, (void *)pool);
pthread_join(tid, (void **)&ret);
printf("ret:%d.\n", ret);
int i;
for (i = 0; i < POOL_NUM; i++)
{
pthread_join(pool->tid[i], (void **)&ret);
printf("%ld ret:%d.\n", pool->tid[i], ret);
}
return 0;
}
queue.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "queue.h"
struct node
{
void *element;
struct node *next;
};
struct queue
{
struct node *front;
struct node *rear;
int count;
};
queue_t *queue_init(void)
{
queue_t *q;
q = (queue_t *) malloc(sizeof(struct queue));
if (q == NULL)
return NULL;
q->front = q->rear = NULL;
q->count = 0;
return q;
}
int queue_isempty(queue_t *q)
{
return q->front == NULL;
}
void *queue_enqueue(queue_t *q, unsigned int size)
{
struct node *n;
n = (struct node *)malloc(sizeof(struct node));
if (n == NULL)
return NULL;
n->next = NULL;
n->element = (void *)malloc(size);
if (n->element == NULL)
return NULL;
if (q->rear == NULL)
{
q->front = q->rear = n;
}
else
{
q->rear->next = n;
q->rear = n;
}
q->count++;
return n->element;
}
void *queue_dequeue(queue_t *q)
{
struct node *n;
void *element;
if (q->front == NULL)
{
printf("queue is empty");
}
n = q->front;
if (q->front == q->rear)
{
q->front = q->rear = NULL;
}
else
{
q->front = q->front->next;
}
element = n->element;
q->count--;
free (n);
return element;
}
void queue_display(queue_t *q)
{
struct node *n;
int *element;
if (queue_isempty(q))
{
printf("queue is empty.\n");
return;
}
n = q->front;
while(n)
{
element = (int *)n->element;
printf("element:%d.", *element);
n = n->next;
}
printf("\n");
return;
}
void queue_destroy(queue_t *q)
{
struct node *n, *tmp;
if (queue_isempty(q))
return;
n = q->front;
while(n)
{
tmp = n;
free(tmp->element);
free(tmp);
n = n->next;
}
return;
}
#if 0
int main(int argc, char *argv[])
{
queue_t *q;
int i;
int *element;
q = queue_init();
if (q == NULL)
{
printf("queue init error.\n");
return -1;
}
for (i = 0; i < 5; i++)
{
element = queue_enqueue(q, sizeof(int));
*element = i+ 'A';
queue_display(q);
}
for (i = 0; i < 4; i++)
{
element = queue_dequeue(q);
queue_display(q);
//printf("element:%d.\n", *element);
free(element);
}
#if 1
queue_destroy(q);
#endif
return 0;
}
#endif
queue.h
typedef struct queue queue_t;
queue_t *queue_init(void);
int queue_isempty(queue_t *q);
void *queue_enqueue(queue_t *q, unsigned int size);
void *queue_dequeue(queue_t *q);
void queue_destroy(queue_t *q);
Makefile
CC=gcc
CFLAGS = -Wall -g
LDHEARD =
LDFLAGS = -lpthread
objects = thread_pool.o queue.o
####################################################
# $@ -- 目标文件
# $^ -- 所有的依赖文件
# $< -- 第一个依赖文件
# $(LDFLAGS) -- 链接所需要的库
####################################################
thread_pool:$(objects)
$(CC) $^ -o $@ $(LDFLAGS)
####################################################
# 这个规则表示所有的.o文件都是依赖与相应的.c文件的;
# 例如add.o依赖于add.c。这个阶段只编译不链接
####################################################
.c.o:
$(CC) -c $< $(CFLAGS) $(LDHEARD)
.PHONY: all clean
clean:
-rm -fr *.o *~ a.out thread_pool