Loading

11.手写线程池及GDB调试

代码

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>


#define LIST_INSERT(item, list) do {          \
    item->prev = NULL;                        \
    item->next = list;                        \
    if ((list) != NULL) (list)->prev = item;  \
    (list) = item;                            \
} while (0)


#define LIST_REMOVE(item, list) do {                         \
    if (item->prev != NULL) item->prev->next = item->next;   \
    if (item->next != NULL) item->next->prev = item->prev;   \
    if (item == list) list = item->next;                     \
    item->prev = item->next = NULL;                          \
} while (0)



struct nTask {
    void (*task_func)(struct nTask *task);
    void *user_data;
    
    struct nTask *prev;
    struct nTask *next;
};


struct nWorker {
    pthread_t threadid;
    int terminate;
    struct nManager *manager;

    struct nWorker *prev;
    struct nWorker *next;
};


typedef struct nManager {
    struct nTask *tasks;
    struct nWorker *workers;

    pthread_mutex_t mutex;
    pthread_cond_t cond;
} ThreadPool;


static void *nThreadPoolCallback(void *arg) {

    struct nWorker *worker = (struct nWorker*)arg;

    while (1) {
        pthread_mutex_lock(&worker->manager->mutex);
        while (worker->manager->tasks == NULL) {
            if (worker->terminate) break;
            pthread_cond_wait(&worker->manager->cond, &worker->manager->mutex);
        }

        if (worker->terminate) {
            pthread_mutex_unlock(&worker->manager->mutex);
            break;
        }

        struct nTask *task = worker->manager->tasks;
        LIST_REMOVE(task, worker->manager->tasks);

        pthread_mutex_unlock(&worker->manager->mutex);
        task->task_func(task);
    }

    free(worker);
}


// API
int nThreadPoolCreate(ThreadPool *pool, int numWorkers) {

    if (pool == NULL) return -1;
    if (numWorkers < 1) numWorkers = 1;
    memset(pool, 0, sizeof(ThreadPool));

    pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;
    memcpy(&pool->cond, &blank_cond, sizeof(pthread_cond_t)); 

    pthread_mutex_init(&pool->mutex, NULL);

    int i = 0;
    for (i = 0; i < numWorkers; i++) {
        struct nWorker *worker = (struct nWorker*)malloc(sizeof(struct nWorker));
        if (worker == NULL) {
            perror("malloc");
            free(worker);
            return -2;
        }
        memset(worker, 0, sizeof(struct nWorker));
        worker->manager = pool;
        int ret = pthread_create(&worker->threadid, NULL, nThreadPoolCallback, worker);
        if (ret) {
            perror("pthread_create");
            return -3;
        }
        LIST_INSERT(worker, pool->workers);
    }

    return 0;
}

// API
int nThreadPoolDestroy(ThreadPool *pool) {

    if (!pool) return -1;

    struct nWorker *worker = NULL;

    for (worker = pool->workers; worker != NULL; worker = worker->next) {
        worker->terminate = 1;
    }

    pthread_mutex_lock(&pool->mutex);

    pthread_cond_broadcast(&pool->cond);

    pthread_mutex_unlock(&pool->mutex);

    pool->workers = NULL;
    pool->tasks = NULL;
    pthread_mutex_destroy(&pool->mutex);
    pthread_cond_destroy(&pool->cond);

    return 0;
}

// API
int nThreadPoolPushTask(ThreadPool *pool, struct nTask *task) {

    pthread_mutex_lock(&pool->mutex);

    LIST_INSERT(task, pool->tasks);

    pthread_cond_signal(&pool->cond);

    pthread_mutex_unlock(&pool->mutex);

}


// sdk  -->  debug thread pool

#if 1

#define THREADPOOL_INIT_COUNT 20
#define TASK_INIT_SIZE        1000

void task_entry(struct nTask *task) {

    int idx = *(int*)task->user_data;
    printf("idx: %d\n", idx);

    free(task->user_data);
    free(task);

}


int main(void) {

    ThreadPool pool;

    nThreadPoolCreate(&pool, THREADPOOL_INIT_COUNT);

    int i = 0;
    for (i = 0; i < TASK_INIT_SIZE; i++) {
        struct nTask *task = (struct nTask *)malloc(sizeof(struct nTask));
        if (task == NULL) {
            perror("malloc");
            exit(1);
        }
        memset(task, 0, sizeof(struct nTask));
        task->task_func = task_entry;
        task->user_data = malloc(sizeof(int));
        *(int*)task->user_data = i;

        nThreadPoolPushTask(&pool, task);
    }

    getchar();

    nThreadPoolDestroy(&pool);

    return 0;
}

#endif

编译

gcc -o threadpool threadpool.c -lpthread

GDB调试指令

gcc -o threadpool threadpool.c -lpthread -g

gdb ./threadpool 

b 111  # 断点

r  # 运行

c  # 继续运行
posted @ 2025-02-09 10:12  lotuslaw  阅读(22)  评论(0)    收藏  举报