1.初识线程池:
根据任务量预先创建一些线程,阻塞等待,一旦有任务到来,随即唤醒一个空闲的线程执行任务。(自己理解)
根据系统自身的环境情况,有效的限制执行线程的数量,使得运行效果达到最佳。线程主要是通过控制执行的线程的数量,超出数量的线程排队等候,等待有任务执行完毕,再从队列最前面取出任务执行。(百度)
2.线程池作用:
减少创建和销毁线程的次数,每个工作线程可以多次使用
可根据系统情况调整执行的线程数量,防止消耗过多内存
3.例题: 创建4个调用线程,然后主线程每次负责向全局变量box填一个数据,数据填好后4个线程中某个线程将数据取出并分析是否包含数字'0' 最后主线程分配完成后 通过取消机制取消取数据的线程
首先需要做的是对线程加互斥量合条件变量,保证数据填一次取一次,但是会有两个问题:
1.取消请求发出后会在次线程的任何时间发生,所以应该对次线程加取消状态设置,并设置取消点,防止打断次线程做任务,导致数据丢失
2.加了取消状态标志后还有一种情况发生,就是部分线程会永远无法关闭,造成阻塞;
原因:线程做完任务后有两种情况响应取消请求,一种是在取消点正常退出,另一种是阻塞在等待状态时取消 ,如:(while(flag!=0) { pthread_cond_wait(&full) } )
取消请求发出后首先会唤醒该线程,如果能持有锁则退出线程,同时由于没有解锁则会造成锁的缺失,剩余的线程被唤醒后因为得不到锁则会继续阻塞,造成进程最终无法终止。
原因概括:如果线程睡眠时被_cacel唤醒,则需要拿到锁,如果没有锁则会继续等待
解决方案:运用线程退出清理程序,释放锁 (由于是响应取消请求,刚好符合退出清理程序使用条件)
连锁问题:既然运用退出清理程序,那么解锁即可,但是锁有个规则:有加才有减,谁加谁减,我们怎么知道该线程退出时是否解锁了呢?
解决:加一个_trylock()函数,如果有锁则立即返回,用于检测是否加锁
cleanExit()//退出清理函数,解决线程退出未释放锁的问题
{
{
pthread_mutex_trylock(&mm);//检测是否加锁
pthread_mutex_unlock(&mm)//解锁
}
4.拓展
4.拓展
需求:如果突然系统并发量较大,线程池内的线程数量不够用,可以创建一些新的临时线程来处理该数据(类似于请个兼职),做完后自动释放,不用主线程等待回收(detach分离状态解决)
问:如和才能够知道线程池内线程是否够用呢?
剖析:一旦有任务则会激活一个睡眠中的线程,如果所有线程都在工作,此时主线程则会阻塞,等待某个次线程处理完成以后再来处理该数据;
解决:将pthread_cond_wait(&empty,&mm);//等待次线程处理完成的信号标志
更还为pthread_cond_timedwait(&empty,&mm);//如果超过设定时间,则会返回,说明线程池线程都处于忙碌状态,此时可以再创建一个临时线程来处理该数据。