编写一个线程池

线程:  

        为什么需要线程池? thread_pool

应用程序创建对象,然后又销毁对象很消耗资源的。

如果我们搞一个程序 去复制一个目录:(有10000个文件)

找到一个文件名,创建一个线程去做复制文件的工作。

因此:预先创建有限数量的线程。加入先创建20个线程, 另外一方面,去搜索目录,找到文件名:把要复制的文件的任 务挂到任务队列上

线程:不停的去看 有没有还未完成的任务

                有:就去完成任务

                没有: 休息,等通知

于是:一些“池化资源”技术就产生了

  主进程:main 要做的事情

1. 初始化一个线程池

        init_pool(thread_pool *pool, unsigned int threads_num);

        thread_pool : 自定义的一个 描述线程池的 数据结构(结构体)

        threads_num: 初始化 要干活的线程数,这些线程都是做同样的工作

                        线程的工作: 取任务,完成任务

2. 添加任务 : 把 do_task函数,arg 参数, 添加到链表中去

        add_task(pool,do_task,(void *)arg);

将任务 do_task 挂到一个任务队列中去,并且通知线程

         pthread_cond_signal

3. 销毁线程池

        destroy_pool(thread_pool *pool);

        通知干活的线程 可以退出了(公司注销),------>设置一个标志: shutdown =1

等待干活的线程回来

销毁一些资源:锁,条件变量

================================线程 ==================================

线程怎么干活? 其实就是考虑 pthread_create的 第三个参数 arg 该怎么写

假设我们对这个函数取名叫做:routine

        while(1)

        {

                         while( 没有新任务 && 系统还未退出shutdown==0)

                                休息,等通知 pthread_cond_wait(&cond, &lock)

                        if( 没有新任务 && shutdown==1)

                 准备撤(线程退出) pthread_exit

                        if( 有新任务) 执行新任务

                                (): 取任务,完成任务

        }

若干个任务怎么去描述?===》任务队列: 链表

到底任务要什么事情?

当前,什么事情都可以做,把要做的事情定义到 函数里面,传给 do_task

我们的例子:把任务安排成:复制文件

显示我们的任务里面需要传参数: 源文件 目的文件 fd

//任务节点:链表

struct task

{

        void *(*do_task)(void *arg); //函数指针,指向任务要执行的函数

        void *arg;// 传给do_task的参数

        struct task *next;

};

===================================pool==================================

我们可以定义一个结构体: thread_pool

为什么设置一个池子? 控制任务的数量不能太多,不能涌入太多的任务。

设置线程的数量,控制这些任务不能同时运行。

定义一个常量:MAX_WAITING_TASK 表示纪录当前正在等待的任务数。

在 pool 结构中定义一个 active_threads 来记录当前到底又几个线程在干活。

任务队列 task_list 链表, 是很重要的公共资源(添加任务,取任 务),父进程和干活的线程都要访问它,所有要对它进行保护。 互斥锁 +条件变量

bool init_pool(thread_pool *pool, unsigned int threads_num)

{

//初始化lock,cond

        shutdown = 0;

         waiting_tasks = 0;

        active_threads = threads_num;

初始化 task_list

        tids = (pthread_t *)malloc(threads_num*sizeof(pthread_t));

创建 active_threads 个线程

}

================================条件变量 cond==============================

在线程的 routine 函数中,在某些情况下,线程会进入休眠状态。 需要等待某个条件出来再唤醒它。 谁来唤醒它?

        1. 父进程退出=======> destroy_pool :

                唤醒所有线程

        2. 来了任务 =======> add_task

                唤醒一个等在 cond 条件变量上的线程

                pthread_cond_signal

===================================互斥锁 lock =============================

需要包含对象: pool->waiting_tasks , pool->task_list

怎么判别要不要包含? 公共的变量可能存在并发的情况下,在我们的项目中:需要加锁的函数:

                        routine , add_task

=====================================main================================

我们的项目就是实现: cp 源文件 目的文件

为了体现多线程,我们允许原文件和目的文件是目录

步骤:

1. 调用 pool_init初始化线程池

2. 怎么去构造 N个任务,其中每个任务仅仅是 copy srcf detf

        难点: 实现 copydir 函数

        copydir

        {

                遍历 src 目录下的所有文件(普通文件 ,目录文件)

                 如果是普通文件: copyfile

                如果是目录文件: copydir

        }

3. 销毁线程池

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值