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  # 继续运行

作者:lotuslaw

出处:https://www.cnblogs.com/lotuslaw/p/18705792

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   lotuslaw  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2023-02-09 15-批次之间具有堆叠的LSTM
2023-02-09 14-LSTM多步预测-多步预测的LSTM网络
2023-02-09 13-LSTM多步预测-静态模型预测
2023-02-09 12-LSTM多变量-定义&训练模型
2023-02-09 11-LSTM多变量-LSTM数据预处理_tmp
2023-02-09 10-LSTM多变量-LSTM数据预处理
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示