【vc post源码】【python水饺源码】【竞技炮源码】thread源码查看

时间:2024-12-28 22:42:40 来源:礼券自助提货系统源码 分类:娱乐

1.UE4源码剖析——异步与并行 中篇 之 Thread
2.Qt——QThread源码浅析
3.【Poco笔记】线程Thread
4.android 为什么不建议使用Thread.stop
5.详解java Thread中的源码join方法
6.Android ActivityThread类在哪个包

thread源码查看

UE4源码剖析——异步与并行 中篇 之 Thread

       我们知道UE中的异步框架分为TaskGraph与Thread两种,上篇教程我们学习了TaskGraph,源码它擅长处理有依赖关系的源码短任务;本篇教程我们将学习Thread,它与TaskGraph相反,源码它更擅长于处理长任务。源码而下一篇文章,源码vc post源码我们则会承接Thread,源码去学习一下引擎中一些重要的源码线程。

       Thread擅长处理长任务,源码从长任务生命周期这个层面来看,源码我们可以先把长任务分为两类:常驻型长任务与非常驻型长任务。源码

       常驻型长任务侧重于并行,源码通常用于监听式服务,源码例如网络传输,源码使用单独的源码线程对网络进行监听,每当有网络数据包到达时,线程接收并处理后,不会立即结束,而是重置部分状态,继续监听,等待下一轮数据包。

       非常驻型长任务侧重于异步,python水饺源码通常用于数据处理,例如主线程为了提高性能,避免卡顿,会将一些重负载的运算任务分发给分线程处理,可能分批给多条分线程,主线程继续运行其他逻辑。任务处理完成后,将结果返回给主线程,分线程可销毁。

       接下来,我们通过两个例子学习Thread的使用。

       计算由N到M(N和M为大数字)所有数字的和。使用Thread异步调用,将计算操作交由分线程执行,计算完成后再通知主线程结果,代码实现如下:

       逻辑分为两部分:启动分线程计算数字和,使用Async函数,参数为EAsyncExecution::Thread,创建新线程执行。学习Async函数用法,该函数返回TFuture对象,竞技炮源码代表未来状态,当前无法获取结果,但在未来某个时刻状态变为Ready,此时可通过TFuture获取结果。

       主线程注册回调,等待分线程计算完成,使用TFuture的Then函数,完成时触发注册的回调,也可使用Wait系列函数等待计算完成。

       接下来学习常驻型任务使用。

       定义玩家血量上限点,当前点,当血量未满时,每0.2秒恢复1点血量。代码实现分为创建生命治疗仪FRunnable对象、重写Run函数、创建FRunnableThread线程、测试恢复功能和释放线程资源。

       生命治疗仪创建与测试完整代码如下,可验证生命恢复功能和暂停与恢复。

       UE4中的mrp软件源码FRunnable与FRunnableThread提供创建常驻型任务所需接口。无论是常驻型还是非常驻型,底层实现相同,都是使用FRunnableThread线程。

       FRunnableThread线程结构包含标识符、逻辑功能、效率与性能、辅助调试字段。线程创建与生命周期分为创建FRunnable类对象、创建FRunnableThread对象两步,通过FRunnable的生命周期管理实现线程运行与停止。

       UE4线程管理流程包括继承并创建FRunnable类对象、创建FRunnableThread对象,生命治疗仪线程创建代码。

       UE4中的几种异步方式底层使用线程实现,学习了线程类型、创建、生命周期、销毁方法,为下篇学习引擎特殊线程打下基础。

Qt——QThread源码浅析

       在探索Qt的多线程处理中,QThread类的小玩法源码实现源码历经变迁。在Qt4.0.1和Qt5.6.2版本中,尽管QThread类的声明相似,但run()函数的实现有所不同。从Qt4.4开始,QThread不再是抽象类,这标志着一些关键调整。

       QThread::start()函数在不同版本中的核心代码保持基本一致,其中Q_D()宏定义是一个预处理宏,用于获取QThread的私有数据。_beginthreadex()函数则是创建线程的核心,调用QThreadPrivate::start(this),即执行run()函数并发出started()信号。

       QThread::run()函数在Qt4.4后的版本中,不再强制要求重写,而是可以通过start启动事件循环。在Qt5.6.2版本中,run函数的定义更灵活,可以根据需要进行操作。

       关于线程停止,QThread提供了quit()、exit()和terminate()三种方式。quit()和exit(0)等效,用于事件循环中停止线程,而terminate()则立即终止线程,但不推荐使用,因为它可能引发不稳定行为。

       总结起来,QThread的核心功能包括线程的创建、run函数的执行以及线程的结束控制。从Qt4.4版本开始,QThread的使用变得更加灵活,可以根据需要选择是否重写run函数,以及如何正确地停止线程。不同版本间的细微差别需要开发者注意,以确保代码的兼容性和稳定性。

【Poco笔记】线程Thread

        Poco的Thread是对标准库std::thread的封装,同时它类似Java一样,提供了Runnable接口。所以使用上是对标Java的。

        与标准库不同的是,Poco::Thread创建和运行时相分离的。这一点标准库设计确实不太友好。例如下面例子。

        同样看例子

        由上面可见,使用基本跟Java类似。创建与运行也分离了。

        看一下主要的运行接口,摘自Poco1.9源码

        源码文件主要包含

        1.Thread.h/Thread.cpp

        提供外部调用接口

        在Thread.cpp中定义了两种Holder, RunnableHolder和CallableHolder。Holder技术是Poco框架中经常用到的,是对某一种类型对象的指针包装。

        Runnable为线程运行类的基类,

        Callable为带一个参数的方法

        2.Thread_POSIX.h/Thread_POSIX.cpp

        3.Thread_VX.h/Thread_VX.cpp

        4.Thread_WIN.h/Thread_WIN.cpp

        5.Thread_WINCE.h/Thread_WINCE.cpp

        这几个文件,每个文件中都定义了ThreadImpl,用于不同平台下的具体实现,Thread私有继承ThreadImp,ThreadImp用于哪一个文件由编译宏决定。

        顺便说一下POSIX系统下的实现。因为使用的是c++,当时没有thread类,所以所有的实现都是使用pthread库来实现的。具体的使用请参考pthread技术文档。

        6.ThreadLocal.h/ThreadLocal.cpp

        ThreadLocal中定义了三个类, TLSAbstractSlot类, TLSSlot类, ThreadLocalStorageç±»

        TLSAbstractSlot是基类,TLSSlot是模板类,通过模板技术包裹了具体的类型。ThreadLocalStorage是用于线程存储,具体是通过一个map来实现。

        因为1.9使用的是c++,还没有引用local_thread关键字,所以这里是通过这种方式实现。

        ThreadLocalStorage定义如下

        那么Poco::Thread的tls是如何定义的?

        源码文件比较少,主要如下文件

        1.Thread.h/Thread.cpp

        2.Thread_STD.h/Thread_POSIX.cpp/Thread_VX.cpp/Thread_WIN.cpp

        Thread.h 主要对实现类ThreadImp的包装,并定义了对外接口。

        Thread_STD.h定义了内部实现,主要提供了ThreadImpç±»

        Thread_POSIX.cpp/Thread_VX.cpp/Thread_WIN.cpp分别定义不同平台下的兼容实现

        在Thread_STD.h中定义了几个重要类型

        在Thread.cpp中增加了两种

        private修饰的ThreadData,定义了线程内部数据。 1.9中源码分别定义在各个平台实现类中,这里抽离出来定义在Thread.cpp中。较之前的定义,这里额外的是新增了std::thread指针。因为直接引用了c++中的thread,有些实现直接借助于它。

android 为什么不建议使用Thread.stop

       å½“调用Thread.stop()方法时,会发生以下两种事情:

       1. 即可抛出ThreadDeath异常,在线程的run()方法里面,任何一刻都可能抛出ThreadDeath Error,包括在catch或者finally语句中。

       2. 释放该线程的所有锁。

       å½“线程抛出ThreadDeath异常时,会导致线程的run()方法突然返回来达到停止该线程的目的。这个异常可以在该线程run()任意一个执行点抛出。原则上只要一调用thread.stop()方法,线程会立即停止,并抛出ThreadDeath error,查看了Thread的源代码后才发现,原先Thread.stop0()方法是同步的,而我们工作线程的run()方法也是同步,那么这样会导致主线程和工作线程共同争用同一个锁(工作线程对象本身),由于工作线程在启动后就先获得了锁,所以无论如何,当主线程在调用thread.stop()时,它必须要等到工作线程的run()方法执行结束后才能进行。

       å› æ­¤ï¼Œthread.stop()是不安全的,主要针对于于:释放改线程所持有的所有的锁,而锁的突然释放会导致被保护的数据的不一致性。

       æ­£ç¡®åœæ­¢çº¿ç¨‹æ€»ç»“起来是以下三点:

       1. 使用violate boolean 变量来表示线程是否停止;

       2. 停止线程时,需要调用停止线程的interrupt()方法,因为线程有可能在wait()或者sleep(),提高停止线程的及时性;

       3. 对于blocking IO的处理,尽量使用interruptibleChannel来代替 blocking IO。

详解java Thread中的join方法

       在Java编程中,Thread类的join()方法发挥着关键作用。当需要控制线程执行顺序时,它能让调用线程暂停,直至被调用的线程完成。在主线程(如main())中,join()尤其有用,它会阻止主线程直到目标线程结束,例如:

       当调用t1.join()时,main()线程会被暂停,直到t1线程完全执行完毕,然后main()线程才会继续执行。

       join()方法的工作原理主要依赖于Java内存模型中的同步机制。通过查看Thread类的源码,我们发现join()实际上调用了wait()方法,使调用线程进入等待状态,直到目标线程结束。由于wait()方法前有synchronized修饰,这意味着主线程(t1线程的持有者)会在一个锁定的上下文中等待,如下所示:

       代码等效于:synchronized(this) { wait(); },使得主线程进入等待队列,直到t1线程结束。

       然而,wait()方法本身并不会唤醒主线程,唤醒过程隐藏在Java虚拟机(JVM)的底层。当t1线程执行完毕,JVM会自动调用lock.notify_all()方法,将主线程从等待队列中唤醒。

       总结起来,join()方法的使用需要注意以下两点:

       1. 它让调用线程暂停,直到目标线程结束。

       2. 唤醒机制由JVM内部的notify_all()方法控制,确保线程按照预期顺序执行。

       理解这些原理,能帮助你更有效地管理和控制Java线程。

Android ActivityThread类在哪个包

       åœ¨frameworks/base/core/java/android/app下

       package android.app;

       è¿™ä¸ªç±»æ˜¯éšè—çš„,在api中无法查看,源码显示:

       /

**

        * This manages the execution of the main thread in an

        * application process, scheduling and executing activities,

        * broadcasts, and other operations on it as the activity

        * manager requests.

       

*

        * { @hide}

        */

ThreadPoolExecutor简介&源码解析

       线程池是通过池化管理线程的高效工具,尤其在多核CPU时代,利用线程池进行并行处理任务有助于提升服务器性能。ThreadPoolExecutor是线程池的具体实现,它负责线程管理和任务管理,以及处理任务拒绝策略。这个类提供了多种功能,如通过Executors工厂方法配置,执行Runnable和Callable任务,维护任务队列,统计任务完成情况等。

       创建线程池需要考虑关键参数,如核心线程数(任务开始执行时立即创建),最大线程数(任务过多时限制新线程生成),线程存活时间,任务队列大小,线程工厂以及拒绝策略。JDK提供了四种拒绝策略,如默认的AbortPolicy,当资源饱和时抛出异常。此外,线程池还提供了beforeExecute和afterExecute钩子函数,用于在任务执行前后执行自定义操作。

       当任务提交到线程池时,会经历一系列处理流程,包括任务的执行和线程池状态的管理。例如,如果任务队列和线程池满,会根据拒绝策略处理新任务。使用线程池时,需注意线程池容量与状态的计算,以及线程池工作线程的动态调整。

       示例中,自定义线程池并重写钩子函数,创建任务后向线程池提交,可以看到线程池如何根据配置动态调整资源。但要注意,如果任务过多且无法处理,可能会抛出异常。源码分析中,submit方法实际上是调用execute,而execute内部包含Worker类和runWorker方法的逻辑,包括任务的获取和执行。

       线程池的容量上限并非Integer.MAX_VALUE,而是由ctl变量的低位决定。 Doug Lea的工具函数简化了ctl的操作,使得计算线程池状态和工作线程数更加便捷。通过深入了解ThreadPoolExecutor,开发者可以更有效地利用线程池提高应用性能。