加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_汕头站长网 (https://www.0754zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux 设置java线程池_Linux线程池技术处理多任务

发布时间:2022-10-08 12:50:22 所属栏目:Linux 来源:
导读:  我们知道,系统中执行资源分配的基本单位是进程,每个进程都有自己的数据段,代码段,和堆栈段,在进行切换时需要有比较复杂的上下文切换。进程的创建和切换需要耗费如此大的资源,如果系统需要多任务,那么使用
  我们知道,系统中执行资源分配的基本单位是进程,每个进程都有自己的数据段,代码段,和堆栈段,在进行切换时需要有比较复杂的上下文切换。进程的创建和切换需要耗费如此大的资源,如果系统需要多任务,那么使用进程会极大的增加系统的负荷。所以操作系统引入了线程。线程是进程内独立的一条运行线,是处理器调度的最小单元,可以对进程的内存空间和资源进行访问,并与同意进程中其他线程共享,所以也称为轻量级进程。有了多个控制线程后,在程序设计时就可以把进程设计成在某一时刻能做的事情不止一件,每个线程处理各自独立的任务。这种方法有很多好处。
 
  通过为每种时间类型分配单独的处理线程,可以简化异步处理时间的代码。
 
  多个进程需要操作系统提供复杂 机制才能实现内存和文件描述符的共享,而多个线程可以自动的访问相同的存储地址空间和文件描述符。
 
  有些问题可以分解从而提高整个程序的吞吐量
 
  交互的任务同样可以通过多线程来改善响应时间,多线程可以把程序中处理用户输入的部分和其他部分分开。
 
  每个线程都含有表示执行环境所必须的信息,
 
  线程ID
 
  一组寄存器值
 
  栈
 
  调度优先级和策略
 
  信号屏蔽字
 
  errno变量
 
  线程私有数据
 
  线程同步
 
  我们在处理多任务时,难免的就需要同步机制,尤其在访问共享变量时,通常变量的增量操作分解为以下三步
 
  从内存中读入寄存器
 
  在寄存器中做增量操作
 
  把新值写回内存单元
 
  如果一个进程在步骤2后其他进程对变量进行一系列改变,最终在进程执行步骤3后变量的值还是步骤2寄存器中的值。
 
  所以线程提供一些列机制实现线程间的同步如互斥量,读写锁,条件变量,自旋锁,屏障。
 
  互斥量
 
  可以使用pthread的互斥接口来保护数据,确保同一时间只有一个线程访问数据。互斥量实际上是一把索,在访问保护资源之前需要对互斥量进行加锁,任何线程再次试图对互斥量进行加锁会被阻塞直到当前线程释放互斥量。
 
  当一个以上的线程需要访问动态分配的对象时,我们可以在对象中嵌入引用计数,确保所有使用对象的线程完成数据访问之前,对象内存空间不会被释放。在对引用计数加一减一检查引用技术是否为0都需要锁住互斥量。
 
  从互斥量的使用我们可以看到互斥量的一些局限,一旦一个进程锁住互斥量后,其他进程都无法获得互斥量,并且线程之间也无法有效的实现同步。所以线程还提供了读写锁和条件变量来弥补互斥量的不足。
 
  读写锁
 
  读写锁有三种状态,读模式下加锁,写模式下加锁,不加锁状态。一次只有一个线程能占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。当读写锁在读加锁状态时,所有试图通过读模式对他加锁的线程都可以得到访问权,但是任何希望以写模式对此锁进行加锁 线程都会阻塞,直到所有线程释放他们的读写锁。
 
  条件变量
 
  条件变量给多个线程提供一个会和的场合,条件变量和互斥变量一起使用,允许线程以无竞争的方式等待特定条件的发生。当线程等待一个条件到来时线程池linux,会先用互斥量锁住线程,然后自动把调用线程放在等待条件的线程列表上,对互斥量解锁。这就关闭了条件检查和线程进入休眠状态等待条件这两个操作之间的时间通道,这样线程就不会错过任何条件变化。pthread_cond_wait返回时,互斥量再次被锁住。
 
  有了以上的知识储备,我们开始实现线程池处理多任务的功能
 
  67c609e35eeaf97fc1e99d28c5d87ebc.png
 
  线程池的作用是同步处理工作队列中的作业,只要有一个线程池空闲,任务队列不为控,线程池就会从任务队列上取下一个作业交给空闲线程处理。
 
  我们先构造一个描述线程池的数据结构
 
  typedef struct
 
  20{21pthread_mutex_t queue_lock;
 
  //互斥锁22pthread_cond_t queue_ready;23 //条件变量锁
 
  24Task_queue task_queue;25 //任务队列
 
  26 intshutdown;27 //线程是否关闭
 
  28 pthread_t *threadid;29 //线程ID
 
  30 intmax_thread_num;31 //最大线程数量
 
  32 intcur_task_size;
 
  //当前任务数量33 }Thread_pool;
 
  接下来我们构造一个任务队列
 
  structjob6{7 void *(*process)(void *arg);8 void *arg;9 struct job *next;10};11
 
  12 typedef structqueue13{14 struct job *q_head;
 
  //任务队列头15pthread_rwlock_t q_lock;
 
  //任务读写锁16 }Task_queue;
 
  首先我们要对线程池进行初始化
 
  主要是对互斥锁,条件变量,任务队列,已经描述线程池状态变量的初始化。
 

(编辑:云计算网_汕头站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!