将给定的java 线程队列添加到运行队列中时为什么要先调用中断

问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
先用python实现, 把每一个要处理的参数存放到队列Queue中, 然后创建线程从队列中取出
class ThreadExecuteJob(threading.Thread):
"""Threaded Url Grab"""
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
i = self.queue.get()
print "执行的参数" + str(i)
# 发送执行完毕信号
self.queue.task_done()
except Exception as e:
logging.warning(str(fun) + "---" + str(e.message) + "---" + str(e.args))
def execute_job_thread_pool(queue):
:param queue: 队列
:param arg:
函数的参数
for i in xrange(6):
t = ThreadExecuteJob(queue)
t.setDaemon(True)
if __name__ == "__main__":
import Queue
day_q = Queue.Queue()
for i in xrange(6):
day_q.put(i)
execute_job_thread_pool(day_q)
day_q.join()
用python实现的多线程取出0-5个数打印出来。现在用java粗略实现的如下, 但是队列数据取完了主线程没有停止, 如何让主线程停止,如何像python那样队列数据取完主线程也停止
public class HelloJava8 {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
BlockingQueue s = new LinkedBlockingQueue();
s.put("java");
s.put("python");
s.put("php");
s.put("c++");
s.put("c");
ArrayList&Thread& threadList = new ArrayList&Thread&();
Thread t1 = new Thread(new Consumer("zhangsan", s));
t1.start();
threadList.add(t1);
Thread t2 = new Thread(new Consumer("lisi", s));
t2.start();
threadList.add(t2);
Thread t3 = new Thread(new Consumer("wangwu", s));
t3.start();
threadList.add(t3);
Thread t4 = new Thread(new Consumer("afei", s));
t4.start();
threadList.add(t4);
Thread t5 = new Thread(new Consumer("jb", s));
t5.start();
threadList.add(t5);
for(Thread thread: threadList) {
thread.join();
System.out.println("主线程执行完毕");
class Consumer implements Runnable {
private BlockingQueue s =
public Consumer(String name, BlockingQueue s) {
this.name =
public void run() {
while (true) {
String product = (String) s.take();
System.out.println(name + "消费(" + product.toString() + ").");
System.out.println("===============");
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
Consumer类的run方法中,while的条件应该改为!s.isEmpty()。主线程未能执行结束的原因是子线程都没有结束造成的,因为BlockingQueue.take()造成了阻塞,看一下文档中写的
take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入
也就是说当BlockingQueue中的对象被消费完毕之后,再次调用其take方法,就会进入等待状态,而题主在程序中使用while(true)作为循环条件,则所有的线程都会不断的调用队列的take方法,而进入阻塞状态,无法退出线程,子线程无法退出,则join之后的主线程System.out.println("主线程执行完毕");则永远在等待,无法执行,故主线程也无法退出。
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
家境小康, 积分 1360, 距离下一级还需 640 积分
论坛徽章:0
这里分析一下最普遍的情况,就是fork系统调用创建的thread,新创建的thread最终都要添加到系统中某个cpu的运行队列中,这样才能
得到调度运行,在do_fork函数的最后阶段,会调用调度程序相关的sched_add函数将新创建的thread添加到系统中某个cpu的运行队列中。
发现之前的帖子中有些用语不是很严谨,比如tdq_cpu[cpu]应该是per processor runqs and statistics,而在此之前称之为运行队列;
实际上struct tdq对象中的tdq_realtime,tdq_timeshare,tdq_idle成员才被称为运行队列。
现在为了和前面保持一致,将tdq_realtime,tdq_timeshare,tdq_idle成员标识的运行队列称为tdq_realtime队列,tdq_timeshare队列,
tdq_idle队列,不过这样并不影响理解ULE调度程序的实现原理。
[ULE线程调度-sched_add函数]:/**************************************************************************************
* Select the target thread queue and add a thread to it.&&Request
* preemption or IPI a remote processor if required.
& &参数描述:
& &td:标识将要被添加到cpu运行队列中的线程。
& &flags:传递给函数sched_add的标志,相关标志需要结合上下文分析,这里暂且略过。
*******************************/
&&2342& & & &
&&2343& & & & void
&&2344& & & & sched_add(struct thread *td, int flags)
&&2345& & & & {
&&2346& & & & & & & & struct tdq *
/***************************************************************************
* 这里将局部变量更改为smp_cpu,以和下面的分析语句中的cpu区别
***********************************/
&&2347& & & & #ifdef SMP
&&2348& & & & & & & & int smp_
&&2349& & & & #endif
&&2350& & & &
&&2351& & & & & & & & KTR_STATE2(KTR_SCHED, &thread&, sched_tdname(td), &runq add&,
&&2352& & & & & & & && &&&&prio:%d&, td-&td_priority, KTR_ATTR_LINKED,
&&2353& & & & & & & && &&&sched_tdname(curthread));
&&2354& & & & & & & & KTR_POINT1(KTR_SCHED, &thread&, sched_tdname(curthread), &wokeup&,
&&2355& & & & & & & && &&&KTR_ATTR_LINKED, sched_tdname(td));
&&2356& & & & & & & & SDT_PROBE4(sched, , , enqueue, td, td-&td_proc, NULL,
&&2357& & & & & & & && &&&flags & SRQ_PREEMPTED);
&&2358& & & & & & & & THREAD_LOCK_ASSERT(td, MA_OWNED);
/*******************************************************************************
* Recalculate the priority before we select the target cpu or
* run-queue.
& &:
& &struct thread对象的td_pri_class成员,即newtd的调度类:
& &u_char& & & & & & & & td_pri_& & & & (t) Scheduling class.&&
& &#define PRI_TIMESHARE& && && &&&3& && & Time sharing process.
& &如果new_thread的调度类为PRI_TIMESHARE,此时就要调用函数sched_priority
& &重新计算newtd的优先级。
& &一般情况下,系统中所有thread的调度类都从thread0(0号线程)继承而来,在系统
& &初始化时,将thread0的调度类设置为PRI_TIMESHARE。除非某些应用程序执行一个
& &rtprio系统调用显式修改线程的调度类,否则线程的调度类通常都为PRI_TIMESHARE。
& &但是这个修改也被限制为下面三种调度类:
& &#define PRI_REALTIME& && && && &2& && & /* Real time process. */
& &#define PRI_TIMESHARE& && && &&&3& && & /* Time sharing process. */
& &#define PRI_IDLE& && && && && & 4& && & /* Idle process. */
***********************************/
&&2363& & & & & & & & if (PRI_BASE(td-&td_pri_class) == PRI_TIMESHARE)
&&2364& & & & & & & & & & & & sched_priority(td);
/***************************************************************************************
* :SMP系统
* Pick the destination cpu and if it isn't ours transfer to the
* target cpu.
& &2370:函数sched_pickcpu为线程td挑选一个合适的cpu,局部变量smp_cpu保存了该
& && && &cpu的logical cpu id。
& &2371:函数sched_setcpu主要完成下面的工作:
& && && &将和线程td相关联的struct td_sched数据对象的ts_cpu成员设置为smp_cpu。
& && && &并返回logical cpu id为smp_cpu的运行队列,这里假设为&tdq_cpu[smp_cpu]。
& && && && && && &
& &2372:函数tdq_add将线程td添加到内嵌在tdq指向的struct tdq数据对象
& && && &中tdq_realtime队列,tdq_timeshare队列,tdq_idle队列中的一个,
& && && &见下面的简要分析。
***********************************/
&&2365& & & & #ifdef SMP
&&2366
&&2367
&&2368
&&2369
&&2370& & & & & & & & smp_cpu = sched_pickcpu(td, flags);
&&2371& & & & & & & & tdq = sched_setcpu(td, smp_cpu, flags);
&&2372& & & & & & & & tdq_add(tdq, td, flags);
/*******************************************************************
* :
& &如果smp_cpu和当前cpu的logical cpu id不相等,那么就调用函数
& &tdq_notify检查线程td是否能够抢占当前正在cpu logical id为smp_cpu
& &上运行的线程,并根据需要发送一个处理器间中断。
&&函数tdq_notify见下面的简要分析。
*******************************************/
&&2373& & & & & & & & if (smp_cpu != PCPU_GET(cpuid)) {
&&2374& & & & & & & & & & & & tdq_notify(tdq, td);
&&2375& & & & & & & & & & & &
&&2376& & & & & & & & }
&&2377& & & & #else
/*****************************************************************
* :单处理器系统,SMP系统的特殊情况,相关函数已经分析。
******************/
&&2378& & & & & & & & tdq = TDQ_SELF();
&&2379& & & & & & & & TDQ_LOCK(tdq);
&&2380& & & & & & & & /*
&&2381& & & & & & & &&&* Now that the thread is moving to the run-queue, set the lock
&&2382& & & & & & & &&&* to the scheduler's lock.
&&2383& & & & & & & &&&*/
&&2384& & & & & & & & thread_lock_set(td, TDQ_LOCKPTR(tdq));
&&2385& & & & & & & & tdq_add(tdq, td, flags);
&&2386& & & & #endif
/**************************************************************************************
* 执行到这里的话,或者系统不是SMP,或者smp_cpu和当前cpu的logical id相等。
& &#define SRQ_YIELDING 0x0001 We are yielding (from mi_switch).
& &如果没有设置SRQ_YIELDING标志,那么td可能就要抢占当前正在运行的thread,此时不需要
& &发送处理器间中断,因为在同一个cpu上,
& &此时:
& &函数sched_setpreempt在条件满足的情况下,简单的设置正在当前cpu上运行thread的
& &TDF_NEEDRESCHED标志,这样当从中断或者系统调用返回时,就会调用mini_switch函数。
*****************************************/
&&2387& & & & & & & & if (!(flags & SRQ_YIELDING))
&&2388& & & & & & & & & & & & sched_setpreempt(td);
&&2389& & & & }复制代码[函数tdq_add]:/*******************************************************************************************
* Add a thread to a thread queue.&&Select the appropriate runq and add the
* thread to it.&&This is the internal function called when the tdq is
* predetermined.
* 参数描述:
& &tdq:指向相应的cpu运行队列。
& &td:将要被添加到运行队列中的thread。
& &flags:一些标志。
& &函数tdq_add实际上调用函数tdq_runq_add将线程td添加到tdq_realtime队列,tdq_timeshare队列,
& &tdq_idle队列三个中的一个。
******************************/
&&2321& & & & void
&&2322& & & & tdq_add(struct tdq *tdq, struct thread *td, int flags)
&&2323& & & & {
&&2324& & & &
&&2325& & & & & & & & TDQ_LOCK_ASSERT(tdq, MA_OWNED);
&&2326& & & & & & & & KASSERT((td-&td_inhibitors == 0),
&&2327& & & & & & & && &&&(&sched_add: trying to run inhibited thread&));
&&2328& & & & & & & & KASSERT((TD_CAN_RUN(td) || TD_IS_RUNNING(td)),
&&2329& & & & & & & && &&&(&sched_add: bad thread state&));
&&2330& & & & & & & & KASSERT(td-&td_flags & TDF_INMEM,
&&2331& & & & & & & && &&&(&sched_add: thread swapped out&));
&&2332& & & &
/***************************************************************************************
* :
& &更新struct tdq对象中的tdq_lowpri成员。从这里可以看出来,tdq_lowpri成员保存的是相应
& &CPU运行队列中线程的最高优先级(数值小)。
& &2335:调用函数tdq_runq_add,见下面的简要分析。
& &2336:函数tdq_load_add简单的递增cpu运行队列tdq的tdq_load成员。
& && && &即struct tdq对象的tdq_load成员:
& && && &tdq_load:对应cpu的负载,sched_highest函数和函数sched_lowest使用该成员。
**********************************************/
&&2333& & & & & & & & if (td-&td_priority & tdq-&tdq_lowpri)
&&2334& & & & & & & & & & & & tdq-&tdq_lowpri = td-&td_
&&2335& & & & & & & & tdq_runq_add(tdq, td, flags);
&&2336& & & & & & & & tdq_load_add(tdq, td);
&&2337& & & & }复制代码[函数tdq_runq_add]:/*******************************************************************************
* Add a thread to the actual run-queue.&&Keeps transferable counts up to
* date with what is actually on the run-queue.&&Selects the correct
* queue position for timeshare threads.
* 参数的含义和上面tdq_add函数的参数相同。
******************************/
& &446& & & & static __inline void
& &447& & & & tdq_runq_add(struct tdq *tdq, struct thread *td, int flags)
& &448& & & & {
& &449& & & & & & & & struct td_sched *
& &450& & & & & & & & u_
& &451& & & &
& &452& & & & & & & & TDQ_LOCK_ASSERT(tdq, MA_OWNED);
& &453& & & & & & & & THREAD_LOCK_ASSERT(td, MA_OWNED);
& &454& & & &
/*******************************************************************************
* 455:pri为线程td的优先级。
& &456:td指向和线程td相关联的struct td_sched数据对象。
& &457:
& &#define& & & & TD_SET_RUNQ(td)& & & & & & & & (td)-&td_state = TDS_RUNQ
& &此时线程td将要被添加到cpu运行队列中,其状态设置为TDS_RUNQ。
& &458-461:
& &#define& && &&&THREAD_CAN_MIGRATE(td)& && &&&((td)-&td_pinned == 0)
& &struct thread对象的td_pinned成员,函数sched_pin会递增该成员,
& &如果该成员非零,就表示线程addtd不能被迁移到其它cpu的运行队列中:& && &&&
& &int& && && && && & td_pinned;Temporary cpu pin count.
& &struct tdq对象的tdq_transferable成员:
& &tdq_transferable: 一个计数器,cpu的相应运行队列中可迁移线程的数目。
& &在td_pinned成员为0时,此时就表示td是可迁移线程,此时递增tdq_transferable,
& &同时设置一个标志,标识线程td是可以迁移的。
& &#define TSF_XFERABLE&&0x0002 Thread was added as transferable
****************************************************/
& &455& & & & & & & & pri = td-&td_
& &456& & & & & & & & ts = td-&td_
& &457& & & & & & & & TD_SET_RUNQ(td);
& &458& & & & & & & & if (THREAD_CAN_MIGRATE(td)) {
& &459& & & & & & & & & & & & tdq-&tdq_transferable++;
& &460& & & & & & & & & & & & ts-&ts_flags |= TSF_XFERABLE;
& &461& & & & & & & & }
/*******************************************************************************
* #define PRI_MIN_BATCH& && && &&&152
& &#define PRI_MAX_BATCH& && && &&&223
& &struct td_sched对象的ts_runq成员,即相关联的thread将被添加到ts_runq
& &指向的队列中:
& &struct runq& &&&*ts_& &&&Run-queue we're queued on.
& &462-464:
& &如果线程td的优先级pri小于152,就将线程td添加到tdq_realtime队列中。
& &464-486:
& &如果线程td的优先级小于或者等于223,就将线程td添加到tdq_timeshare队列中。
& &这之间的代码还要根据条件计算一个pri等,这个不是很清楚,大家可以帮忙看看。
& &487-488:
& &如果线程td的优先级pri大于223,就将线程td添加到tdq_idle队列中。
& &函数runq_add_pri和函数runq_add不属于ULE线程调度实现源代码定义的,这两个
& &函数是简单的链表操作,大家感兴趣的话,可以参考一下:
& &&$FreeBSD: release/9.2.0/sys/kern/kern_switch.c&这个c源文件。& &
****************************/
& &462& & & & & & & & if (pri & PRI_MIN_BATCH) {
& &463& & & & & & & & & & & & ts-&ts_runq = &tdq-&tdq_
& &464& & & & & & & & } else if (pri &= PRI_MAX_BATCH) {
& &465& & & & & & & & & & & & ts-&ts_runq = &tdq-&tdq_
& &466& & & & & & & & & & & & KASSERT(pri &= PRI_MAX_BATCH && pri &= PRI_MIN_BATCH,
& &467& & & & & & & & & & & & & & & & (&Invalid priority %d on timeshare runq&, pri));
& &468& & & & & & & & & & & & /*
& &469& & & & & & & & & & & &&&* This queue contains only priorities between MIN and MAX
& &470& & & & & & & & & & & &&&* realtime.&&Use the whole queue to represent these values.
& &471& & & & & & & & & & & &&&*/
& &472& & & & & & & & & & & & if ((flags & (SRQ_BORROWING|SRQ_PREEMPTED)) == 0) {
& &473& & & & & & & & & & & & & & & & pri = RQ_NQS * (pri - PRI_MIN_BATCH) / PRI_BATCH_RANGE;
& &474& & & & & & & & & & & & & & & & pri = (pri + tdq-&tdq_idx) % RQ_NQS;
& &475& & & & & & & & & & & & & & & & /*
& &476& & & & & & & & & & & & & & & &&&* This effectively shortens the queue by one so we
& &477& & & & & & & & & & & & & & & &&&* can have a one slot difference between idx and
& &478& & & & & & & & & & & & & & & &&&* ridx while we wait for threads to drain.
& &479& & & & & & & & & & & & & & & &&&*/
& &480& & & & & & & & & & & & & & & & if (tdq-&tdq_ridx != tdq-&tdq_idx &&
& &481& & & & & & & & & & & & & & & && &&&pri == tdq-&tdq_ridx)
& &482& & & & & & & & & & & & & & & & & & & & pri = (unsigned char)(pri - 1) % RQ_NQS;
& &483& & & & & & & & & & & & } else
& &484& & & & & & & & & & & & & & & & pri = tdq-&tdq_
& &485& & & & & & & & & & & & runq_add_pri(ts-&ts_runq, td, pri, flags);
& &486& & & & & & & & & & & &
& &487& & & & & & & & } else
& &488& & & & & & & & & & & & ts-&ts_runq = &tdq-&tdq_
& &489& & & & & & & & runq_add(ts-&ts_runq, td, flags);
& &490& & & & }复制代码[函数tdq_notify]:/*******************************************************************************
* Notify a remote cpu of new work.&&Sends an IPI if criteria are met.
& &和上下文联系起来分析函数tdq_notify会更清晰。
& &对于logical cpu id为x的cpu,此时参数描述及相应成员的取值如下:
& &参数描述:
& &tdq:为&tdq_cpu[x]。
& &td:已经被添加到运行队列tdq_cpu[x]的tdq_realtime队列,tdq_timeshare队列,
& && & tdq_idle队列三个队列之一中的线程。
& &成员取值描述:
& &
& &td-&td_sched-&ts_cpu的值为x。
*****************************************/& && && &&&
&&1010& & & &&&*/
&&1011& & & & static void
&&1012& & & & tdq_notify(struct tdq *tdq, struct thread *td)
&&1013& & & & {
&&1014& & & & & & & & struct thread *
&&1015& & & & & & & &
&&1016& & & & & & & &
&&1017& & & && && && &
/************************************************************
* :
& &如果struct tdq对象的tdq_ipipending成员非零,就表示已经
& &有一个挂起的处理器间中断,此时直接返回。
*****************************/
&&1018& & & & & & & & if (tdq-&tdq_ipipending)
&&1019& & & & & & & & & & & &
/**********************************************************************
* 1020: 根据假设,这里cpu的值为x。
& &1021:pri设置为线程td的优先级。
& &1022:ctd标识当前正在cpu x上运行的线程。
& && && && && &
& &:
& &sched_shouldpreempt函数根据线程td的优先级和线程ctd的优先级
& &检查线程td是否能够抢占线程ctd,返回值1表示可以抢占;
& &返回值0表示不能抢占,见下面的简要分析。
*************************************/
&&1020& & & & & & & & cpu = td-&td_sched-&ts_
&&1021& & & & & & & & pri = td-&td_
&&1022& & & & & & & & ctd = pcpu_find(cpu)-&pc_
&&1023& & & & & & & & if (!sched_shouldpreempt(pri, ctd-&td_priority, 1))
&&1024& & & & & & & & & & & &
/***********************************************************************
* #define TD_IS_IDLETHREAD(td)& & & & ((td)-&td_flags & TDF_IDLETD)
& &#define& & & & TDF_IDLETD&&0x This is a per-CPU idle thread.
& &: 如果ctd为per-CPU idle thread就进行相关的处理。
& && && && &&&这里暂时忽略。
**********************************/
&&1025& & & & & & & & if (TD_IS_IDLETHREAD(ctd)) {
&&1026& & & & & & & & & & & & /*
&&1027& & & & & & & & & & & &&&* If the MD code has an idle wakeup routine try that before
&&1028& & & & & & & & & & & &&&* falling back to IPI.
&&1029& & & & & & & & & & & &&&*/
&&1030& & & & & & & & & & & & if (!tdq-&tdq_cpu_idle || cpu_idle_wakeup(cpu))
&&1031& & & & & & & & & & & & & & & &
&&1032& & & & & & & & }
/***************************************************************
* 如果执行到这里,就表示线程td将抢占线程ctd。
* 1033:将struct tdq对象的tdq_ipipending成员设置为1。
& &1034:发送类型为IPI_PREEMPT的处理器间中断。
& &又碰到处理器间中断了,在SMP系统中,处理器间中断非常
& &重要,打算下次跟大家分享一下在intel平台下,处理器
& &间中断的发送及处理过程。
********************************/
&&1033& & & & & & & & tdq-&tdq_ipipending = 1;
&&1034& & & & & & & & ipi_cpu(cpu, IPI_PREEMPT);
&&1035& & & & }复制代码[函数sched_shouldpreempt]:/***************************************************************************
* sched_shouldpreempt根据优先级判断是否能够抢占,返回值1表示可以抢占;返回
& &值0表示不能抢占。
& &参数描述:
& &pri:将要抢占的thread的优先级,这里假设为td1。
& &cpri:将要被抢占的thread的优先级,这里假设为td2。
& &remote:标识是否是同一个cpu。
*************************************/& && && &&&
& &408& & & & static inline int
& &409& & & & sched_shouldpreempt(int pri, int cpri, int remote)
& &410& & & & {
/***************************************************************************
* If the new priority is not better than the current priority there is
* nothing to do.
& &415-416:
& &如果415行的if条件为真,就表示td1的优先级比td2的优先级低,此时不需要
& &抢占,返回值为0.数值越大,优先级越低。
***********************************/
& &414& & & & & & & &&&
& &415& & & & & & & & if (pri &= cpri)
& &416& & & & & & & & & & & & return (0);
/************************************************************************
* Always preempt idle.
& &420-421:
& &#define PRI_MIN_IDLE& && && && &(224)
& &如果420行的if条件为真,就表示td2为idle线程,这种情况下总是抢占td2.
& &返回值为1。
*****************************/
& &419& & & & & & & &&&
& &420& & & & & & & & if (cpri &= PRI_MIN_IDLE)
& &421& & & & & & & & & & & & return (1);
& &422& & & & & & & &
& &423
/***************************************************************
* If preemption is disabled don't preempt others.
& &425-431:
& &#define PRI_MAX_IDLE& && && && &(PRI_MAX) 255
& &#define PRI_MIN_KERN& && && && &(80)
& &开启或禁用kernel thread preemption。
& &[1]:对应430-431行。
& &只有当编译了内核选项PREEMPTION时,preempt_thresh的值
& &才非零,此时kernel thread preemption才有效,分两种情况:
& &编译了FULL_PREEMPTION选项时:
& &preempt_thresh被设置为PRI_MAX_IDLE,表示始终进行抢占。
& && && &&&
& &没有编译FULL_PREEMPTION选项时:
& &preempt_thresh被设置为PRI_MIN_KERN,只有当线程优先级
& &小于或者等于PRI_MIN_KERN时,才进行抢占。此时,
& &preempt_thresh相当于一个抢占阈值,只有当pri低于这个阈值时,
& &才进行抢占。
& && && && && && &
& &[2]:对应425-426行。
& &当没有编译内核选项PREEMPTION时,preempt_thresh的值被
& &设置为0,此时禁止kernel thread preemption。
***************************************/
& &425& & & & & & & & if (preempt_thresh == 0)
& &426& & & & & & & & & & & & return (0);
& &427& & & & & & & & /*
& &428& & & & & & & &&&* Preempt if we exceed the threshold.
& &429& & & & & & & &&&*/
& &430& & & & & & & & if (pri &= preempt_thresh)
& &431& & & & & & & & & & & & return (1);
/****************************************************************
* If we're interactive or better and there is non-interactive
* or worse running preempt only remote processors.
& &436-437:
& &#define PRI_MAX_INTERACT& && &&&151
& &436行if语句条件全为真就表示线程td1的交互性程度比线程td2的
& &交互性程度高,此时需要抢占td2.
***************************************/
& &436& & & & & & & & if (remote && pri &= PRI_MAX_INTERACT && cpri & PRI_MAX_INTERACT)
& &437& & & & & & & & & & & & return (1);
& && && && && & /* 如果执行到这里,就表示不需要抢占,函数返回值为0 */
& &438& & & & & & & & return (0);
& &439& & & & }复制代码
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp

我要回帖

更多关于 java 多线程 队列 的文章

 

随机推荐