Linux下的C语言线程池

来源:互联网 发布:maxwell软件原理 编辑:程序博客网 时间:2024/05/01 10:56

    线程池的目的是为了减少线程创建、销毁所带来的代价,当有非常多的任务需要独立的线程去做时,可以使用线程池,从线程池中获取线程来处理一个个任务。

    本文就来实现一个线程池。实现环境为Linux操作系统,采用C语言实现pthread线程的线程池。


基本方法如下几点:

  • pthread线程
  • 构造双向链表维持待完成任务队列
  • 使用线程信号量sem_t控制线程池
  • 使用线程互斥锁pthread_mutex_t保护任务队列

设计思路:

    线程池狭义将其实是若干个组成的数组,如果是静态数组,那么线程个数保持不变;如果是动态数组,那么可以让线程的个数随着任务量需求的变化而变化。线程一旦创建就不再销毁,而是一直存在,当要处理任务时就需要调用对应的任务;当没有任务时就阻塞起来。

    任务由队列组织起来,形成一个任务队列,采用先入先出的优先处理原则。

    线程池的主线程负责创建线程池中的子线程、添加新任务。子线程负责从任务队列中摘取任务来执行。


线程分配设计:

    线程池中的每个子线程都是等价的。我们用线程信号量来控制子线程和任务的分配问题。设置一个信号量来表示任务队列中的任务资源。每个子线程都会处于死循环中,每轮循环首先等待一个任务资源信号量,当等到之后,互斥地从任务队列中摘取一个任务结点,任务结点中记录着该任务所要执行的函数指针及其参数。之后子线程开始执行该任务。执行完之后释放一个信号量并进入下一轮循环。当没有信号量小于1时,子线程将会阻塞。

    因此一个任务由哪一个线程来执行,这要看哪个线程能够获取到对应的信号量资源。


具体实现:

    任务队列由双向链表构造,每个节点包含一个任务的函数指针和参数指针。

typedef struct thpool_job_t{    void*  (*function)(void* arg);        void*                     arg;        struct thpool_job_t*     next;       struct thpool_job_t*     prev;  }thpool_job_t;
    任务队列拥有一个任务资源信号量,用来控制线程的分配。

typedef struct thpool_jobqueue{    thpool_job_t *head;              thpool_job_t *tail;             int           jobsN;            sem_t        *queueSem;                            }thpool_jobqueue;
    线程池的结构体,记录了线程数组、线程个数、任务队列。
typedef struct thpool_t{    pthread_t*       threads;       int              threadsN;       thpool_jobqueue* jobqueue;   }thpool_t;

实现细节:点击这里

0 0
原创粉丝点击