简单的线程池和队列搭配使用

一个简单的线程池和队列的搭配使用

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 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值