linux 下 c++ 多线程的实现

来源:互联网 发布:软件测试方法分类 编辑:程序博客网 时间:2024/05/23 13:46

看了不少文章,好多都很复杂,终于今天写了一个线程池,大概架构如下

Task类,很简单就是完成具体的任务,c上是用struct存储的,c的具体的process(),用一个函数指针

class Task{        public:                Task();                ~Task();                int process();  //任务所需的处理函数        private:                int data;  //任务所需数据}

TaskQueue类,就是保存任务的队列,封装了一些操作,也很简单,c中用的链表实现可以

class TaskQueue{        public:                TaskQueue();                ~TaskQueue();                int insert(Task* task);                int getQueueSize();                Task* getOneTask();        private:                list<Task*> task_list;                pthread_mutex_t task_list_mutex;};

所要主要的是添加任务的时候要枷锁。

ThreadPool类,用mutex,cond实现线程的等待同步,也很简单,但添加一个任务的时候,发送一个信号,看看有没有等待中的线程,有的话就开始处理,任务很多,每个线程就while循环的处理,最重要的是要注意同步。很简单的实现,需要改进的是动态的增加线程数目。其实当线程满负荷的时候,也可以动态增加进程的数目,而且有的时候,增加进程的数目很有必要,因为单个进程所开的线程数目有限制的。

class ThreadPool{public:  ThreadPool ();  ThreadPool (int thread_num);   ~ThreadPool ();  int poolInit ();  int addTask (Task* task);  TaskQueue* getTaskQueue();  static void *start_thread(void *args);  int run();private:  int thread_num;  TaskQueue* task_queue;  pthread_mutex_t queue_lock;  pthread_cond_t queue_ready;  pthread_t *thread_id;};


下面是论坛上看来的,有助于自己理解,防止自己理解不透彻,特地原封的写在下面

1, 线程池就是一堆线程, 没任务就阻塞着.

2, 任务就是一个结构体, 内含数据, 以及处理数据的函数指针, 为了通用性, 大致写成这样:
struct task
{
  void *data; //数据
  int (*handler)(void *ctx); //处理数据
};

这样就把不同类型的任务抽象出来了, 用户指定方法, 提供数据就行了.

3, 任务的分派, 线程的管理. 这里就看需求了, 处理办法也很多样.  
①可以做任务队列(mutex+cond),让线程池去竞争。
②可以做事件驱动的, 也就是每个线程自己做select等待任务分发, 每个线程有自己的任务队列,这种方法控制更加简单灵活,可控性很强。

线程的管理方面工作不一定很复杂,可以在①的模型下外加一个变量来做控制, 也可以利用信号来做控制,都是摆脱不掉全局变量的互斥访问的, 尤其在线程控制这一块, 比进程控制要麻烦的多。

线程退出与否,没有办法获得,不像进程那样调用一个非阻塞的waitpid试探一下就可以了,一旦没有线程退出而调用了pthread_join就会阻塞,而且join没法被信号中断, 也就没法设计setitime来按周期中断阻塞,所以必须维护全局信息来记录线程的退出状况,控制线程必须定期轮询,这是目前web服务器必然的设计方式,也就是控制线程必须轮询,不可能有一种方法达到完全的异步。

线程池管理比较简单灵活可控的是方法②,按照我的想法是完全可以异步的,主控线程和线程池完全的异步,主控线程当然也需要轮询,目的是及时跟进线程池状态,以便进行线程数量控制。

0 0
原创粉丝点击