线程的回收

1.
    wait
    waitpid //1.理解函数的功能
            //2.使用 
              
 2.线程 
   a.线程概念 
   b.线程 与 进程关系 
     线程存在于进程中 
     
     线程  --- 执行的单位 
     进程  --- 资源分配单位 
     
    创建 和 调度 
  c.线程组成 
  d.线程操作 (函数接口)
   创建线程 pthread_create   
            posix thread create 
   线程执行 ---体现在线程执行函数 (回调函数)
   线程退出 ---pthread_exit()  
           线程结束方式:
           1.pthread_exit   //pthread_join
           2.从线程执行函数中return  //此时效果等价于pthread_exit 
           3.pthread_cancel  //线程可以被取消 
           4.任何一个线程调用了exit 
             或者 
             主线程 (main函数) return 
            都会造成 进程结束  
   线程资源回收 ---pthread_join
   
   
    int pthread_cancel(pthread_t thread);
    功能:
        发送 取消的请求 
    参数:
        thread   //表示要发送的线程的tid号 
    返回值:
        成功 0
        失败 错误码 
        
        

   线程资源回收 
   1.pthread_join    //需要自己回收  ---线程的属性 (可结合性)  --- 一般是子线程 在较短时间内运行完 
   2.pthread_detach  //可分离属性    ---子线程运行很久才结束 ---  设置分离属性 
  
  
  函数:
     pthread_detach(); 
     
    int pthread_detach(pthread_t thread);
    功能:
         分离线程 
    参数:
        thread 要分离的线程的tid
    返回值:
          成功 0
        失败 错误码 
---------------------------------------------------------------
总结:
1.创建 -- pthread_create 
2.执行 -- 线程执行函数 
3.退出 -- pthread_exit 
          return  //线程执行函数中 
          pthread_cancel 
          exit() //return 从main   
4.资源回收 
       可结合性 --- pthread_join    //这种用于 ,线程任务较短,主线程需要关心子线程状态 
       可分离性 --- pthread_detach  //子程序执行任务较长,主线程也不需要关心子线程状态 
    
-----------------------------------------------------------------
对比 线程 和 进程 

1.线程 vs 进程 
线程 CPU执行的最小单位 
进程 资源分配和任务调度基本单位 

2. 各自特点 (优缺点)

 //1.创建 和 调度
  线程 
      创建速度快 
      调度速度快 
      
      //并发程度 更高 
      
 //2. 安全性 
    
    线程 
        好处:
        共享了进程的数据空间 
        共享数据方面 方便 
        缺点:
          安全性不好                   //
          带来资源竞争                //专门的技术 解决资源竞争  --- 互斥 同步 
    进程 
        进程空间相互独立 
        好处,
            安全性好 
        缺点:
            进程间共享数据不方便      //进程间通信   (管道,信号,共享内存)
            
     
 //3. 编程
 
--------------------------------------------------------------------------------
线程间的资源竞争:
   共享资源:    临界资源
   临界区  :    访问共享资源(临界资源)那段代码 
   
   
机制:
    互斥锁   
    互斥     排他性   --- 要么不访问 要访问就是一次完整操作  (原子操作)
    锁        //
    
    //软件层面上的锁 
    
    
    //锁的操作机制 
        框架:
     定义互斥锁 ==》初始化锁 ==》加锁 ==》解锁 ==》销毁
        ****                      ***      ***
    
    
    
   定义互斥锁:
    pthread_mutex_t   mutex;
    互斥锁类型        互斥锁变量 内核对象 
    
   初始化锁
    pthread_mutex_init(); //初始化一把锁    
    
   
   加锁                      //加锁 加在 要访问临界资源的地方 
       pthread_mutex_lock(); //上锁 
   解锁 
       pthread_mutex_unlock(); //解锁  临界资源访问之后就解开
   销毁
       pthread_mutex_destroy();//销毁一把锁 
    


 pthread_mutex_init()    
 功能:
      初始化 互斥锁 
      
     int pthread_mutex_init(
                     pthread_mutex_t *restrict mutex,
           const pthread_mutexattr_t *restrict attr
                           ); 
    参数:
      @mutex     //就是要初始化的 互斥锁变量 
      @attr      //属性  
                 //NULL 默认属性  --- 普通锁 
                 //读写锁 
                 
                 
       int pthread_mutex_lock(pthread_mutex_t *mutex);
       int pthread_mutex_trylock(pthread_mutex_t *mutex);
       int pthread_mutex_unlock(pthread_mutex_t *mutex);

       参数:
          @mutex    //要操作的那把锁 
        
       int pthread_mutex_destroy(pthread_mutex_t *mutex); //用完之后锁要销毁         
          
练习:
    定义一个全局char buf[20];

    线程1
         把0~9 这10个     数字字符依次存放到buf中
         for (i = 0; )
         然后 打印  //printf("%s\n",buf);
    线程2    
         把abcdefghij 这10个 字母字符依次存放到buf中
         然后 打印   //printf("%s\n",buf); 
  
  
总结:
   //锁是一种线程间 同步机制 
   //互斥锁 -- 保证线程对于共享资源的排他性访问 。 
               保证每个线程访问时的原子性操作 
               
  //操作 
  //初始化 一把锁 
  //   动态初始化 pthread_mutex_init
  //   静态初始化 用初始化的宏 
  //加锁 
  //解锁
  //销毁 
--------------------------------------------------------------
#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;

void* increment_counter(void* arg) 
{
    for (int i = 0; i < 10000; ++i)
    {
        // 锁定互斥锁,等待直到获得锁
        pthread_mutex_lock(&mutex);
        // 安全地更新计数器
        counter++;
        printf("Counter is now %d\n", counter);
        // 释放互斥锁
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;

    // 创建两个线程
    pthread_create(&t1, NULL, increment_counter, NULL);
    pthread_create(&t2, NULL, increment_counter, NULL);

    // 等待线程结束
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("Final counter value is %d\n", counter);
    return 0;
}

------------
#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;

void* increment_counter_trylock(void* arg) 
{
    for (int i = 0; i < 10000; ++i) 
    {
        // 尝试锁定互斥锁
        if (pthread_mutex_trylock(&mutex) == 0) 
        {
            // 成功获取锁,更新计数器
            counter++;
            printf("Counter is now %d\n", counter);
            // 释放互斥锁
            pthread_mutex_unlock(&mutex);
        } else {
            // 未能获取锁,可以做一些其他的事情或者简单地重试
            // 这里我们选择简单的重试
            continue;
        }
    }
    return NULL;
}

int main() {
    pthread_t t1, t2;

    // 创建两个线程
    pthread_create(&t1, NULL, increment_counter_trylock, NULL);
    pthread_create(&t2, NULL, increment_counter_trylock, NULL);

    // 等待线程结束
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("Final counter value is %d\n", counter);
    return 0;
}
-----------------------------------------------------------------
 

<think> 我们正在讨论线程池的线程回收策略。根据用户提供的引用内容,我们可以总结如下: 1. 线程池中的线程分为核心线程和非核心线程(尽管内部实现可能不区分,但逻辑上有这样的概念)。 2. 线程回收主要针对非核心线程,当它们空闲时间超过keepAliveTime时会被回收。 3. 核心线程默认不会回收,除非显式设置allowCoreThreadTimeOut为true。 4. 线程回收的发生时机是在工作线程从工作队列中获取任务时,如果等待超过keepAliveTime且当前线程数大于核心线程数,则回收线程。 我们需要详细解释线程池的线程回收策略,包括回收条件、回收过程以及如何配置。 另外,根据引用[5],线程池创建线程的规则也值得注意,因为回收策略与线程池的状态和线程数量密切相关。 回答结构建议: 1. 核心线程与非核心线程的概念 2. 默认回收策略(非核心线程超时回收,核心线程回收) 3. 如何配置核心线程超时回收(allowCoreThreadTimeOut) 4. 回收的具体触发时机和过程 5. 回收策略的重要性(避免资源泄漏,动态调整线程数) 同时,生成相关问题。 注意:引用内容已在用户输入中给出,我们需要在回答中适当引用(在相关句子末尾添加[^n])。 </think> ### 线程线程回收策略详解 #### 一、核心回收机制 1. **非核心线程回收** 当线程池中线程数超过核心线程数(`corePoolSize`)时: - 空闲线程在等待新任务时,若超过`keepAliveTime`时限会被自动回收[^3] - **回收触发点**:线程从工作队列(`workQueue`)获取任务时的等待超时 2. **核心线程保护** - 核心线程默认不会被回收(即使空闲)以维持基础服务能力[^3] - 可通过`allowCoreThreadTimeOut(true)`显式开启核心线程超时回收[^3] #### 二、回收流程与条件 ```mermaid graph TD A[线程尝试从workQueue获取任务] --> B{等待超过keepAliveTime?} B -->|是| C{当前线程数 > corePoolSize?} C -->|是| D[回收线程] C -->|否| E[保持存活等待任务] B -->|否| E ``` 关键控制点: 1. **线程数量阈值**:仅当`当前线程数 > corePoolSize`时才触发回收 2. **空闲时间窗口**:`keepAliveTime`参数决定空闲等待时长(单位:TimeUnit) 3. **队列状态**:回收发生在从阻塞队列获取任务时(如`LinkedBlockingQueue.take()`) #### 三、设计原理与资源管理 | **机制** | **作用** | **影响** | |----------------------|-------------------------------------------------------------------------|----------------------------------| | 默认保护核心线程 | 避免高频任务反复创建线程的开销 | 提升高频请求响应速度[^4] | | 动态回收非核心线程 | 自动释放闲置资源 | 减少内存占用和CPU竞争[^1] | | 超时回收开关(`allowCoreThreadTimeOut`) | 适应突发流量场景 | 可能导致核心服务能力波动[^3] | **示例场景**: 线程池配置 `corePoolSize=5`, `maximumPoolSize=10`, `keepAliveTime=60s`: 1. 流量高峰创建10线程 2. 流量下降后,5个非核心线程空闲超60秒被回收 3. 最终保留5个核心线程待命 #### 四、关键注意事项 1. **资源泄漏风险** 若不显式关闭线程池(`shutdown()`),部分线程可能永久驻留内存[^2] ```java // 正确关闭示例 executor.shutdown(); while (!executor.isTerminated()) { /* 等待终止 */ } ``` 2. **队列类型影响** - `SynchronousQueue`(同步移交):无队列缓冲,立即创建新线程[^4] - `LinkedBlockingQueue`(无界队列):优先使用已有线程回收频率低 - `ArrayBlockingQueue`(有界队列):队列满时才创建线程回收更频繁 3. **守护线程配置** 在Java Web项目中: ```java new ThreadFactoryBuilder().setDaemon(true).build(); // 避免阻止应用关闭[^4] ``` > 最佳实践:通过`ThreadPoolExecutor`构造函数显式配置参数,避免`Executors`默认配置的隐患[^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值