• 如何在Linux下实现你的线程池(Step By Step,Pthread)


    200行C代码就可以实现线程池?开玩笑吧?不,告诉你,我是认真的,200行C代码真的可以实现一个简单可用的线程池!!!

    首先,你应该知道 PThread 吧,如果不知道,那你怎么穿越到我这个页面的,你应该先去看看维基,或者这个这个,什么,你想在Windows系统下使用 pthread,那你应该去这个页面看看啦,亲!咱们先看实现代码吧,木有注释,木有例子 ^0^,下次再给例子,请留意了,今天就到这里吧~~~

    /*
     * =============================================================================
     *
     *       Filename:  tiny-threadpool.h
     *
     *    Description:  tiny threadpool implementation in c.
     *
     *        Created:  09/28/2012 07:37:30 PM
     *
     *         Author:  Fu Haiping (forhappy), haipingf@gmail.com
     *        Company:  ICT ( Institute Of Computing Technology, CAS )
     *
     * =============================================================================
     */
    #ifndef TINY_THREADPOOL_H
    #define TINY_THREADPOOL_H
    #include <pthread.h>
    
    typedef struct _tthreadpool_s tthreadpool_t;
    typedef struct _tthread_s tthread_t;
    typedef struct _tjob_s tjob_t;
    
    struct _tthreadpool_s {
        tthread_t *threads;
        tjob_t *jobs;
        int num_jobs;
        int num_threads;
        pthread_mutex_t jobs_mutex;
        pthread_mutex_t num_jobs_mutex;
        pthread_cond_t jobs_not_empty_cond;
        pthread_cond_t jobs_not_full_cond;
    };
    
    struct _tthread_s {
        pthread_t thread_id;
        tthreadpool_t *pool;
        tthread_t *prev;
        tthread_t *next;
        int killed;
    };
    
    struct _tjob_s {
        void (*job_function)(tjob_t *job);
        void *user_data;
        tjob_t *prev;
        tjob_t *next;
    };
    
    extern int
    tthreadpool_init(tthreadpool_t *pool, int numWorkers);
    
    extern void
    tthreadpool_shutdown(tthreadpool_t *pool);
    
    extern void
    tthreadpool_add_job(tthreadpool_t *pool, tjob_t *job);
    
    extern void
    tthreadpool_add_job_ex(tthreadpool_t *pool, tjob_t *job);
    
    extern void
    tthreadpool_wait(tthreadpool_t *pool);
    
    #endif // TINY_THREADPOOL_H
    /*
     * =============================================================================
     *
     *       Filename:  tiny-threadpool.c
     *
     *    Description:  tiny threadpool implementation in c.
     *
     *        Created:  09/28/2012 07:37:20 PM
     *
     *         Author:  Fu Haiping (forhappy), haipingf@gmail.com
     *        Company:  ICT ( Institute Of Computing Technology, CAS )
     *
     * =============================================================================
     */
    #include <assert.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "tiny-threadpool.h"
    
    #define ADD_THREAD(item, list) { \
        item->prev = NULL; \
        item->next = list; \
        list = item; \
    }
    
    #define REMOVE_JOB(item, list) { \
        if (item->prev != NULL) item->prev->next = item->next; \
        if (item->next != NULL) item->next->prev = item->prev; \
        if (list == item) list = item->next; \
        item->prev = item->next = NULL; \
    }
    
    static void *thread_function(void *ptr) {
        tthread_t *thread = (tthread_t *)ptr;
        tjob_t *job;
    
        while (1) {
            pthread_mutex_lock(&thread->pool->num_jobs_mutex);
            pthread_mutex_lock(&thread->pool->jobs_mutex);
            while (thread->pool->jobs == NULL) {
                pthread_cond_wait(&thread->pool->jobs_not_empty_cond, &thread->pool->jobs_mutex);
            }
            job = thread->pool->jobs;
            if (job != NULL) {
                REMOVE_JOB(job, thread->pool->jobs);
                thread->pool->num_jobs--;
                pthread_cond_signal(&thread->pool->jobs_not_full_cond);
    
            }
            pthread_mutex_unlock(&thread->pool->jobs_mutex);
            pthread_mutex_unlock(&thread->pool->num_jobs_mutex);
            if (thread->killed) break;
            if (job == NULL) continue;
            job->job_function(job);
        }
        free(thread);
        pthread_exit(NULL);
    }
    
    int tthreadpool_init(tthreadpool_t *pool, int num_threads) {
        int i = 0;
        tthread_t *thread;
        pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;
        pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;
    
        if (num_threads < 1) num_threads = 1;
        memset(pool, 0, sizeof(*pool));
        memcpy(&pool->jobs_mutex, &blank_mutex, sizeof(pool->jobs_mutex));
        memcpy(&pool->num_jobs_mutex, &blank_mutex, sizeof(pool->num_jobs_mutex));
        memcpy(&pool->jobs_not_empty_cond, &blank_cond, sizeof(pool->jobs_not_empty_cond));
        memcpy(&pool->jobs_not_full_cond, &blank_cond, sizeof(pool->jobs_not_full_cond));
        pool->num_threads = num_threads;
        pool->num_jobs = 0;
    
        for (i = 0; i < num_threads; i++) {
            if ((thread = malloc(sizeof(tthread_t))) == NULL) {
                fprintf(stderr, "Failed to allocate threads");
                return -1;
            }
            memset(thread, 0, sizeof(tthread_t));
            thread->pool = pool;
            if (pthread_create(&thread->thread_id, NULL, thread_function, (void *)thread)) {
                fprintf(stderr, "Failed to start all threads");
                free(thread);
                return -1;
            }
            ADD_THREAD(thread, thread->pool->threads);
        }
    
        return 0;
    }
    
    void tthreadpool_shutdown(tthreadpool_t *pool) {
        tthread_t *thread = NULL;
    
        for (thread = pool->threads; thread != NULL; thread = thread->next) {
            thread->killed = 1;
        }
    
        pthread_mutex_lock(&pool->jobs_mutex);
        pool->threads = NULL;
        pool->jobs = NULL;
        pthread_cond_broadcast(&pool->jobs_not_empty_cond);
        pthread_mutex_unlock(&pool->jobs_mutex);
    }
    
    void tthreadpool_add_job(tthreadpool_t *pool, tjob_t *job) {
        pthread_mutex_lock(&pool->jobs_mutex);
        ADD_THREAD(job, pool->jobs);
        pthread_cond_signal(&pool->jobs_not_empty_cond);
        pthread_mutex_unlock(&pool->jobs_mutex);
    }
    
    void tthreadpool_add_job_ex(tthreadpool_t *pool, tjob_t *job) {
        pthread_mutex_lock(&pool->jobs_mutex);
    
        while(pool->num_jobs == 2 * pool->num_threads) {
            pthread_cond_wait(&pool->jobs_not_full_cond, &pool->jobs_mutex);
        }
        
        ADD_THREAD(job, pool->jobs);
        pool->num_jobs++;
        pthread_cond_signal(&pool->jobs_not_empty_cond);
        pthread_mutex_unlock(&pool->jobs_mutex);
    }
    
    void tthreadpool_wait(tthreadpool_t *pool) {
        tthread_t *thread = NULL;
        for (thread = pool->threads; thread != NULL; thread = thread->next) {
            pthread_join(thread->thread_id, NULL);
        }
    }
  • 相关阅读:
    Spring HandlerInterceptor的使用
    JAVE 视音频转码
    习课的redis配置记录
    原 HttpClient 4.3超时设置
    IPMI
    Tomcat redis 配置
    JVM route
    linux swap空间的swappiness=0
    【SSH三大框架】Hibernate基础第五篇:利用Hibernate完毕简单的CRUD操作
    英特尔高速存储技术
  • 原文地址:https://www.cnblogs.com/haippy/p/2707668.html
Copyright © 2020-2023  润新知