当前位置: 首页 > wzjs >正文

股票配资系统网站开发深圳福田做网站公司哪家好

股票配资系统网站开发,深圳福田做网站公司哪家好,海山网站建设,永久不收费免费的软件进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位; 线程是进程中的一个执行单元,是 CPU 调度和分派的基本单位; 而协程是一种比线程更加轻量级的并发编程方式,它可以在一个线程中实现多个任务…

        进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位;

        线程是进程中的一个执行单元,是 CPU 调度和分派的基本单位;

        而协程是一种比线程更加轻量级的并发编程方式,它可以在一个线程中实现多个任务的并发执行。

协程比线程使用资源更少的原因
  • 栈空间小:线程的栈空间一般为几 MB,而协程的栈空间通常只有几 KB,大大减少了内存的占用。
  • 创建和销毁开销低:线程的创建和销毁需要操作系统内核的参与,涉及到系统调用,开销较大;而协程的创建和销毁在用户态完成,开销较小。
  • 上下文切换开销小:线程的上下文切换需要保存和恢复寄存器、栈指针等信息,并且涉及到用户态和内核态的转换;而协程的上下文切换只需要保存和恢复少量的寄存器信息,开销较小。

进程、线程、协程对比表

维度进程(Process)线程(Thread)协程(Coroutine)
定义程序在操作系统中的一次执行实例,是资源分配的基本单位。进程内的执行单元,是 CPU 调度的基本单位。用户态轻量级 “线程”,由协程库管理,可在同一线程内协作式调度。
调度单位操作系统内核调度操作系统内核调度协程库(用户态调度,无需内核参与)
上下文切换内核态切换,开销极大(涉及内存地址空间、文件描述符等)。内核态切换,开销较大(涉及寄存器、栈指针等)。用户态切换,开销极小(仅保存协程状态到堆,无需内核干预)。
内存占用独立地址空间(通常数 MB 到 GB 级)。共享进程内存空间,每个线程栈默认约 1 MB。共享线程内存,每个协程仅需几个 KB(无独立栈,共享调用栈)。
并发性进程间并发,由操作系统控制。线程间并发,由操作系统控制(抢占式多任务)。协程间并发,由协程库控制(协作式多任务,需主动挂起)。
创建开销高(需分配独立内存、文件句柄等资源)。中(需分配线程栈、寄存器上下文)。极低(仅创建协程对象,复用线程资源)。
切换开销最高(涉及内核态上下文和地址空间切换)。较高(内核态线程上下文切换)。最低(用户态协程状态保存 / 恢复,无内核参与)。
资源隔离完全隔离(地址空间、文件描述符等)。部分隔离(共享进程内存,独立栈、寄存器)。不隔离(共享线程内存,通过协程作用域管理生命周期)。
执行控制权操作系统完全控制(不可预测抢占)。操作系统完全控制(不可预测抢占)。协程主动控制(通过 suspend 挂起,协作式恢复)。
典型用途独立程序运行(如浏览器、IDE 等独立进程)。多任务处理(如网络请求、文件读写等异步操作)。高并发轻量任务(如海量 I/O 操作、事件驱动逻辑)。
代表技术Linux 进程、Windows 进程。Java 线程、POSIX 线程(pthread)。Kotlin 协程、Go Goroutine、Python asyncio 协程。
生命周期由操作系统管理(创建 / 销毁开销大)。由操作系统管理(依赖进程生命周期)。由协程库管理(绑定作用域,如 Android 的 lifecycleScope)。
上下文保存位置硬盘或内存(进程切换时保存完整状态)。内存(线程栈和寄存器状态)。堆(协程状态封装为 Continuation 对象)。
阻塞影响进程阻塞不影响其他进程。线程阻塞会占用 CPU 时间片,影响同进程内其他线程。协程阻塞不阻塞线程,可释放线程执行其他协程。

核心差异总结

  1. 调度层级

    • 进程和线程由 操作系统内核 调度,属于 内核态并发
    • 协程由 协程库 调度,属于 用户态并发,依赖于线程但更轻量。
  2. 资源开销

    • 进程:资源隔离性最强,但创建和切换开销最大;
    • 线程:共享进程资源,开销中等;
    • 协程:几乎无额外资源开销,可在单线程内运行数万个协程。
  3. 控制方式

    • 进程 / 线程:由操作系统强制抢占,不可预测;
    • 协程:通过 suspend 主动挂起,协作式恢复,适合细粒度异步控制。
  4. 适用场景

    • 进程:适合完全隔离的独立任务;
    • 线程:适合 CPU 密集型或需要系统级并发的任务;
    • 协程:适合 I/O 密集型、高并发轻量任务(如网络请求、UI 异步更新)。

关于 suspend 关键字

概念解释

在 Kotlin 协程中,suspend 关键字用于修饰函数,表明这个函数是一个挂起函数。挂起函数只能在协程内部或者另一个挂起函数中被调用。当调用挂起函数时,协程会暂停执行,直到挂起函数的操作完成,之后再恢复协程的执行。

深入源码理解

从源码层面来看,Kotlin 编译器会对挂起函数进行特殊处理,将其转换为带有状态机的代码。下面结合代码示例深入讲解:

// 使用 suspend 关键字修饰函数,表明这是一个挂起函数
suspend fun getDataFromNetwork(): String {// delay 是 Kotlin 协程库提供的一个挂起函数,用于模拟耗时操作,这里暂停 1000 毫秒delay(1000) return "Data from network"
}// 在协程作用域中启动一个新的协程
GlobalScope.launch {// 调用挂起函数,协程会在此处挂起,等待 getDataFromNetwork 函数执行完成val result = getDataFromNetwork() // 当挂起函数执行完成,协程恢复执行,打印结果println(result) 
}

在编译时,getDataFromNetwork 函数会被转换为一个状态机。以下是简化的状态机代码示例,用于说明其工作原理:

// 定义一个密封类来表示状态机的不同状态
sealed class GetDataFromNetworkState {// 初始状态object Initial : GetDataFromNetworkState() // 等待延迟完成的状态object WaitingForDelay : GetDataFromNetworkState() // 任务完成的状态object Finished : GetDataFromNetworkState() 
}// 模拟编译器转换后的挂起函数
fun getDataFromNetwork(state: GetDataFromNetworkState = GetDataFromNetworkState.Initial): Any? {var currentState = statewhile (true) {when (currentState) {// 初始状态,开始执行挂起函数is GetDataFromNetworkState.Initial -> {// 将状态更新为等待延迟完成currentState = GetDataFromNetworkState.WaitingForDelay // 调用 suspendCoroutine 函数挂起协程,等待延迟完成return suspendCoroutine<Unit> { continuation -> // 模拟延迟 1000 毫秒Thread.sleep(1000) // 延迟完成后,恢复协程执行continuation.resume(Unit) }}// 等待延迟完成的状态is GetDataFromNetworkState.WaitingForDelay -> {// 将状态更新为任务完成currentState = GetDataFromNetworkState.Finished // 返回函数的结果return "Data from network" }// 任务完成的状态,结束状态机is GetDataFromNetworkState.Finished -> {return null}}}
}

协程和多线程 / 线程池的区别

1. 资源消耗
  • 协程
    协程是轻量级的,一个线程可以容纳多个协程。从源码角度看,Kotlin 协程使用 Continuation 接口来管理协程的状态。Continuation 本质上是一个回调接口,它保存了协程的上下文和状态。当协程挂起时,只需要保存当前的 Continuation 对象,而不需要像线程那样保存整个线程栈。以下是 suspendCoroutine 函数的简化示例:
// 定义一个挂起函数,用于挂起协程并执行指定的代码块
suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T =// 调用 suspendCoroutineUninterceptedOrReturn 函数,传入一个 lambda 表达式suspendCoroutineUninterceptedOrReturn { c ->// 创建一个 SafeContinuation 对象,用于保存协程的状态val safe = SafeContinuation(c.intercepted()) // 执行传入的代码块,将 SafeContinuation 对象作为参数传递block(safe) // 获取协程的结果,如果协程还未完成,会抛出异常safe.getOrThrow() }

这里的 SafeContinuation 就是用于保存协程状态的对象,它的创建和销毁开销很小。

  • 多线程 / 线程池
    线程在创建时,操作系统会为其分配一定的栈空间,通常是几兆字节。线程的创建和销毁涉及到操作系统的内核调用,开销较大。线程池虽然可以复用线程,但每个线程仍然需要占用固定的栈空间,当线程数量较多时,会占用大量的系统内存。以下是 Java 中创建线程的示例:
// 创建一个新的线程对象
Thread thread = new Thread(() -> {// 线程执行的代码System.out.println("Thread is running"); 
});
// 启动线程
thread.start(); 
2. 并发控制
  • 协程
    协程是协作式的并发,由开发者控制协程的挂起和恢复。在 Kotlin 协程中,suspend 函数就是控制协程挂起的关键。当协程遇到 suspend 函数时,会调用 Continuation 的 resumeWith 方法将控制权让出。以下是 delay 函数的简化示例:
// 定义一个挂起函数,用于暂停协程指定的时间
suspend fun delay(timeMillis: Long) {// 如果延迟时间小于等于 0,直接返回if (timeMillis <= 0) return // 调用 suspendCancellableCoroutine 函数挂起协程,并在指定时间后恢复return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->// 调用协程上下文的 delay 调度器,在指定时间后恢复协程cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont) }
}
  • 多线程 / 线程池
    多线程是抢占式的并发,由操作系统调度。线程之间竞争 CPU 资源,为了保证线程安全,需要使用同步机制,如 synchronized 关键字或 Lock 接口。以下是使用 ReentrantLock 实现线程同步的示例:
import java.util.concurrent.locks.ReentrantLock;// 定义一个计数器类
class Counter {// 计数器的值private int count = 0; // 创建一个 ReentrantLock 对象,用于线程同步private final ReentrantLock lock = new ReentrantLock(); // 增加计数器的值public void increment() {// 获取锁lock.lock(); try {// 增加计数器的值count++; } finally {// 释放锁lock.unlock(); }}// 获取计数器的值public int getCount() {// 获取锁lock.lock(); try {// 返回计数器的值return count; } finally {// 释放锁lock.unlock(); }}
}
3. 代码编写
  • 协程
    协程可以以同步的方式编写异步代码,避免了回调地狱。例如,使用 withContext 函数切换线程:
// 定义一个挂起函数,用于在 IO 线程中获取数据
suspend fun fetchData() = withContext(Dispatchers.IO) {// 模拟网络请求,暂停 1000 毫秒delay(1000) // 返回获取到的数据"Data from network" 
}

withContext 函数内部会挂起协程,切换到指定的线程池执行任务,任务完成后再恢复协程。

  • 多线程 / 线程池
    多线程编程需要使用回调、FutureHandler 等机制来处理异步操作。以下是使用 ExecutorService 和 Future 来执行异步任务的示例:
import java.util.concurrent.*;public class Main {public static void main(String[] args) {// 创建一个单线程的线程池ExecutorService executor = Executors.newSingleThreadExecutor(); // 提交一个任务到线程池,并返回一个 Future 对象Future<String> future = executor.submit(() -> {// 模拟网络请求,暂停 1000 毫秒Thread.sleep(1000); // 返回获取到的数据return "Data from network"; });try {// 获取任务的结果,如果任务还未完成,会阻塞当前线程String result = future.get(); // 打印任务的结果System.out.println(result); } catch (InterruptedException | ExecutionException e) {// 处理异常e.printStackTrace(); } finally {// 关闭线程池executor.shutdown(); }}
}

这种方式代码逻辑比较复杂,容易出现嵌套和回调地狱的问题。

综上所述,协程在资源消耗、并发控制和代码编写方面都具有明显的优势,尤其适合处理大量的异步任务。在 Android 开发中,合理使用协程可以提高应用的性能和可维护性。


文章转载自:

http://EK8W4puA.mdgpp.cn
http://URduS1Qv.mdgpp.cn
http://5R9M37av.mdgpp.cn
http://9EYgj3JM.mdgpp.cn
http://YafroCfX.mdgpp.cn
http://G0XsWeRC.mdgpp.cn
http://IfNByBG7.mdgpp.cn
http://3v8N9gi4.mdgpp.cn
http://A5w5bRyF.mdgpp.cn
http://ADxwWdOm.mdgpp.cn
http://MJ1xbzxm.mdgpp.cn
http://Jp1qBCIg.mdgpp.cn
http://MaIpjfdL.mdgpp.cn
http://OJMwWgrJ.mdgpp.cn
http://P9W5FZJo.mdgpp.cn
http://4P4OP1Hp.mdgpp.cn
http://7TO9SUoz.mdgpp.cn
http://xEVlu8PX.mdgpp.cn
http://Wz34ahtk.mdgpp.cn
http://CRbT1t08.mdgpp.cn
http://SlUR7B5Q.mdgpp.cn
http://IWDdd5Im.mdgpp.cn
http://BJYpHR4A.mdgpp.cn
http://trcueklW.mdgpp.cn
http://S6olIaT0.mdgpp.cn
http://rS0sqsia.mdgpp.cn
http://UxxwgmXT.mdgpp.cn
http://xfT3fIfj.mdgpp.cn
http://OH8JPHQF.mdgpp.cn
http://mwnej5eM.mdgpp.cn
http://www.dtcms.com/wzjs/664874.html

相关文章:

  • 做家教的网站凡客网站建站教程
  • 网站拥有权安卓商城网站开发
  • 网站权重优化网页设计与制作项目教程陈义文
  • 网站会对特殊的ip做跳转seo的主要工作内容
  • 做网站卖赚钱吗网站名称及网址
  • 做网站有什么好的推荐有什么网站是做中式酒店大堂的
  • 邢台提供网站建设公司报价江西省建设厅网站官网
  • 下载类网站如何做网站开发类论文题目
  • 山西餐饮加盟网站建设网页托管平台排名
  • seo免费优化网站网站平台建设费用的会计核算
  • 网站举报在哪举报今天上海大事件
  • 网站面包屑如何做做视频网站的空间
  • 冀州网站优化重庆市价格信息网官网
  • 外贸行业网站建设国内十大咨询公司排名
  • 建设银行网网站一级建造师求职网
  • 青岛市两个体系建设网站组织架构及营销网络怎么填写
  • 怎样做网站表白墙仿站网站开发
  • 山东建设执业师官方网站做色网站
  • 小说章节收费网站建设济南公司做网站的价格
  • 给网站做数据分析wordpress修改编辑器
  • 广东建设网站北京大兴做环保备案网站
  • 电子商务网站建设模板下载吉利汽车网站开发环境分析
  • 网站建设 平易乐清建站公司
  • 免费推广网站入口2022wordpress填表插件
  • 网站开发的语言有什么软件网站建设公司兴田德润电话
  • 学校网站建设对教学的意义说说网站是怎样建设和推广的
  • 网站静态和动态区别是什么意思设计之家海报
  • 手机网站怎么优化关键词外贸营销员国家职业技能标准
  • 网站推广的含义wordpress搭建网站
  • 服装建设网站的原因泰安网站建设流程