首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏韩曙亮的移动开发专栏

    【Kotlin 底层实现 ② ( 调度器 | 任务泄漏 | 结构化并发 )

    文章目录 一、调度器 二、任务泄漏 三、结构化并发 一、调度器 ---- 是在 调度器 中运行的 , 在中有 3 种调度器 : Dispatchers.Main 调度器 : 在 主线程 Dispatchers.Default 调度器 都是在子线程 中执行耗时任务 , 但是在取消任务方面 , 磁盘或网络操作 与 CPU 密集型操作 是不同的 , 需要采用不同的任务取消策略 , 因此这里将耗时任务分配成两种调度器 ; 二、任务泄漏 ---- 任务泄漏 : 发起 任务 后 , 无法追踪任务的执行结果 , 任务等于无效任务 , 但是仍然会消耗 内存 , CPU , 网络 , 磁盘 等资源 ; Kotlin 中引入了 结构化并发机制 避免 任务泄漏 的情况发生 ; 任务泄漏 与 内存泄漏 类似 ; 三、结构化并发 ---- 结构化并发 使用场景 : 任务取消 : 在不需要任务的时候 , 取消协任务 ; 追踪任务 任务 , CoroutineScope 作用域 可以取消 所有由其启动的任务 ; 常见的 CoroutineScope 作用域 : GlobalScope : 该作用域是 进程级别的

    1.1K20编辑于 2023-03-30
  • 来自专栏Golang实战进阶

    Go-使用和泄漏

    ,这就出现了泄漏;特点是:应用程序的生命周期内存在,为goroutine分配的任何内存都不能释放go泄漏的情况1.没有发送者,导致始终等待首先go是“通过channel来共享内存”,而无缓冲的channel ch中读取数据val := <-ch // 当ch中被填入数据后,触发同步操作,否则该会始终阻塞在这里fmt.Println(val)}()}上面的例子中由于该始终阻塞且无法释放,导致该泄漏如果在某个函数中需要顺序调用另一个函数 即go泄漏发生go泄漏的情况:当go中的发送到无缓冲通道中时,要在接收者接收之前都会进行阻塞,但是当出现超时的情况时,则select则会通过ctx.Done()的方式结束,使得接收器停止接收 ,而导致go始终处于阻塞状态,就发生了go泄漏修复方法:准备一些空间,将无缓冲的通道改为容量cap为1的有缓冲通道ch := make(chan result,1)这样操作后,即使在超时的情况下发送者所在的中仍然可以将 search函数返回的result放到ch中然后结束,从而使得该的内存以及通道ch的内存被回收掉,避免了泄漏2.不完整的工作如下例子中,因为main函数其实在go语言中也是作为一个(主

    43310编辑于 2024-08-25
  • 来自专栏程序员奇点

    Go tool 问题排查- 泄漏问题

    和 Java 有点类似,自带了内存回收, 所以一般不会发生内存泄漏。 但是也不绝对, golang 中 本身是可能泄漏的,或者叫做失控,进而导致内存泄漏。 启动程序 为了能更加图形化的展示,可以安装。 (*Wolf).Drink 在不停地创建没有实际作用的: func (w *Wolf) Drink() { log.Println(w.Name(), "drink") for i := 0; i < 10; i++ { go func() { time.Sleep(30 * time.Second) }() } } 可以看到 Drink 函数 ,每次循环会有创建10个会 sleep 30s 才会退出,如果反复调用这个 Drink 函数, 那么会导致大量出现泄漏数会增加。

    2.3K20发布于 2021-09-15
  • 来自专栏Bennyhuo

    破解 Kotlin (2) - 启动篇

    2. 再来看看的启动 说了这么多线程,原因嘛,毕竟大家对它是最熟悉的。 我们说过,启动需要三样东西,分别是 上下文、启动模式、体,体 就好比 Thread.run 当中的代码,自不必说。 本文将为大家详细介绍 启动模式。 } job.cancel() log(3) 我们创建了后立即 cancel,但由于是 ATOMIC 模式,因此一定会被调度,因此 1、2、3 一定都会输出,只是 2 和 3 的顺序就难说了。 delay(1000) log(3) } job.cancel() log(4) job.join() 我们在 2 和 3 之间加了一个 delay, delay 会使得体的执行被挂起 2 会连续在同一线程中执行, delay 是挂起点,因此 3 会等 100ms 后再次调度,这时候 4 执行, join 要求等待执行完,因此等 3 输出后再执行 5。

    1.4K30发布于 2020-02-20
  • 来自专栏飞鸟的专栏

    十、python学习笔记--爬虫(对比和非效率)

    # 一个简单的小爬虫,将3个页面的数据保存到data.html,对比和非的使用时间 """ 1、通过urlopen获取数据 2、写入文件 3、使用三个页面,通过gevent.joinal执行 (会在IO阻塞处切换),用时短 4、在Windows系统,由于捕获IO较慢。

    1K31编辑于 2022-02-10
  • 来自专栏数据云团

    并发篇-python-2

    遇到阻塞就切换到另一个继续执行 ! gevent 通信 ? # 将函数封装成,并开始调度 >>>producer = gevent.spawn(producer, queue) # 阻塞(一阻塞就切换)等待 >>>gevent.joinall([producer gevent通信 问题引入 问题一: 程之间不是能通过switch通信嘛? >>>是的,由于 gevent 基于 greenlet,所以可以。 问题二: 那为什么还要考虑通信问题?

    44320发布于 2019-07-18
  • 来自专栏Python协程

    2.的应用

    使用也就意味着你需要一直写异步方法。在 Python 中我们使用 asyncio 模块来实现一个。 def function(x): return 2 * xif __name__ == '__main__': t=function(2) asyncio.run(t)注意:主函数里面调用时它是异步函数 asyncio.create_task(function2(3)), ]if __name__ == '__main__': # 一次性启动多个任务() asyncio.run( await 的作用就是等待当前的运行结束之后再继续进行下面代码。 等待一个的执行完毕,如果有返回结果,那么就会接收到的返回结果,通过使用 return 可以返回的一个结果,这个和同步函数的 return 使用方法一样。

    27110编辑于 2024-07-08
  • 来自专栏Bennyhuo

    破解 Kotlin 番外篇(2) - 的几类常见的实现

    2. 1 send 2 receive 2 send 3 receive 3 End Producer End Consumer End Main 通过这个例子,希望大家能够对有一个更加具体的认识,我们看到对于来讲 ,它包括: 的执行体,主要是指启动时对应的函数 的控制实例,我们可以通过创建时返回的实例控制的调用流转 的状态,在调用流程转移前后,的状态会发生相应的变化 说明 Lua 标准库的属于非对称有栈 整段程序的输出如下: wait for read write 0 read 0 write 1 read 1 write 2 read 2 read end 如果我们有多个 go routine 对 181808 read 1 181808 read 2 181808 read end 两个 go routine 除了开始运行时占用了两个线程,后续都在一个线程中转移调度权(不同场景的实际运行结果可能有细微差异

    1.8K31发布于 2020-02-20
  • 来自专栏韩曙亮的移动开发专栏

    【Kotlin 简介 ( 概念 | 作用 | 创建 Android 工程并进行相关配置开发 | 异步任务与对比 )

    文章目录 一、概念 二、作用 三、创建 Android 工程并进行相关配置 1、创建 Android 工程 2、配置环境 3、布局文件 4、异步任务代码示例 5、代码示例 6、完整代码示例 四、异步任务与对比 一、概念 ---- Coroutine 是 Kotlin 语言 中新出现的概念 , 在 Java 语言中没有 ; 是 基于 线程 的 , 是 轻量级 线程 ; 二、作用 ---- 主要作用如下 : 处理耗时任务 : 耗时任务 通常需要 阻塞主线程 , 线程量级太重 , 耗时任务 推荐在中执行 ; 保证主线程安全 : 从主线程中 安全地调用可能会挂起的函数 包下的 Executor,ThreadPoolExecutor,FutureTask 取代 AsyncTask ; 三、创建 Android 工程并进行相关配置 ---- 1、创建 Android New Project " 选项 , 创建工程 , 创建 Empty Activity ; 注意选择 Kotlin 语言 , Android Studio 会自动添加 Kotlin 语言支持 ; 2

    6.2K20编辑于 2023-03-30
  • 来自专栏源码阅读

    -无栈(下)

    里面含有lc_t类型成员变量,本质上是一个unsigned short类型     ·整个PT,在创建之前需要调用PT_INIT进行初始化,初始化之后调用PT_BEGIN拉起运行完毕之后调用 ,一个是timer_thread定时,一个是login_thread登录; ·其中timer_thread负责定时器任务,network_thread负责消息接收并根据消息头拉起对应的登录 ); ·当读到消息之后,对于未开启流程的玩家创建一个,其他的则调度对应的(PT_SCHEDULE(login_thread(role_iter->second)))继续往后走; ·对于登录 ,而外层用name->RoleData的映射关系管理及其他中间态数据;     需要注意的是——以protothread来说: ·对于无栈来说,因为不存在指针等信息,所以无栈的所有信息是可以缓存在共享内存的 ,因此进程可以通过共享内存在重启的环境下,也不会导致中断; ·但是这种恢复也是有条件的,在protothread中是用行号进行恢复,若是用到的源文件的行号出现改变,则可能执行错乱,如下所示

    1.2K20编辑于 2023-03-09
  • 来自专栏C++小白

    小白学笔记2-c语言实现-2021-2-10

    文章目录 前言 一、c语言中切换方式 二、使用setjmp 和 longjmp实现切换 1.setjmp和longjmp函数简介 2.实现 三、使用switch-case实现切换 1 .switch-case小技巧 2.实现 四、使用ucontext实现切换 1.ucontext相关函数简介 2.实现 五、使用汇编语言实现切换 1.X86-64CPU寄存器简介 2 象这样的把 case 标志放在嵌套在 swtich 语句内的模块中是合法的 2.实现 学习了上面的小技巧以后,我们来思考一下,如何使用这个技巧来实现2.实现 学习了前面的四个函数以后,通过一个简单例子看一下实现: #include<ucontext.h> #include<stdio.h> #include<unistd.h> /* 子执行函数 2.实现 当切换时需要保存当前的上下文信息,切换到另一个的上下文进行执行,而这些上下文信息主要就是寄存器的值。

    1.8K20编辑于 2022-02-22
  • 来自专栏韩曙亮的移动开发专栏

    【Kotlin 异常处理 ② ( SupervisorJob | supervisorScope 作用域构建器函数 )

    文章目录 一、SupervisorJob 二、supervisorScope 作用域构建器函数 在上一篇博客介绍了 异常处理 【Kotlin 异常处理 ① ( 根异常处理 , 会将异常 传递给 父 , 父会执行如下操作 : ① 取消子 : 不仅仅取消产生异常的子 , 该父下所有的子都会取消 ; ② 取消父 : 将父本身取消 ; ③ 向父的父传播异常 作用域 创建 val job2 = supervisorScope.launch { delay(100) Log.i(TAG, "子 job2 执行") } 二、supervisorScope Log.i(TAG, "子 job 执行") } val job2 = launch { delay(100) Log.i (TAG, "子 job2 执行") } } }

    1.1K10编辑于 2023-03-30
  • 来自专栏飞鸟的专栏

    十、python学习笔记--非爬虫(对比和非效率)

    # 一个简单的小爬虫,将3个页面的数据保存到data.html,对比和非的使用时间 """非 1、通过urlopen获取数据 2、写入文件 3、使用三个页面,通过for循环执行(非会在IO

    67720编辑于 2022-02-10
  • 来自专栏python3

    的特点是利用任务的阻塞时间去处理其他任务 处理任务的是线程,而是单线程,占用资源由大到小排:多进程>多进程> gevent模块封装greenlet模块,greenlet模块封装yield 在 gevent.sleep,或者使用monkey补丁实现替换 如代码因为monkey.patch_all()补丁问题报错,将from gevent import monkey和补丁代码放到最前面尝试 使用完成多任务三个例子 t1 = func1() t2 = func2() while True: next(t1) next(t2) if __name__ == "__ switch() time.sleep(0.1) def func2(): while True: print("---2---") gr1. --") g2 = gevent.spawn(func2, 5) print("---3---") g3 = gevent.spawn(func3, 5) print("---4---") # 的最大特点就是利用某个任务阻塞的时间去处理其他任务

    78720发布于 2020-01-17
  • 来自专栏zingpLiu

    及Python中的

    1 1.1的概念 ,又称微线程,纤。英文名Coroutine。一句话说明什么是线程:是一种用户态的轻量级线程。 1.2 的优缺点 的优点:   (1)无需线程上下文切换的开销,避免了无意义的调度,由此可以提高性能(但也因此,程序员必须自己承担调度的责任,同时,也失去了标准线程使用多CPU的能力)   (2)无需原子操作锁定及同步的开销   (3)方便切换控制流,简化编程模型   (4)高并发+高扩展性+低成本:一个CPU支持上万的都不是问题。 (2)进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序 2 Python中如何实现 2.1 yield实现   前文所述“子程序(函数)在执行过程中可以中断去执行别的子程序;别的子程序也可以中断回来继续执行之前的子程序 实现,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级

    1.7K20发布于 2018-09-05
  • 来自专栏每日一篇技术文章

    比如你的双手可以同时做两件事,比如吃饭这件事就是并发,吃饭这个过程中,可以同时吃几种菜,甚至喝汤,这个过程就是一个多任务并发的过程,但是并发在时间上是不能同时进行的 2.并发和并行的却别 并行是指<同时 4.Go 是什么? Go 是与其他函数或方法一起并发运行的函数或方法。Go 可以看作是轻量级线程。与线程相比,创建一个 Go 的成本很小。 与函数不同,程序控制不会去等待 Go 执行完毕。在调用 Go 程之后,程序控制会立即返回到代码的下一行,忽略该的任何返回值。 如果希望运行其他 Go ,Go 主必须继续运行着。 信道可用于在其他结束执行之前,阻塞 Go 主。 ++ { fmt.Printf("%d - 第 %d 循环 \n",num, i) } } func main() { go print(1) go print(2)

    89950发布于 2019-06-11
  • 来自专栏C++小白

    小白学笔记1-概念初识-2021-2-10

    文章目录 前言 一、从进程、线程到 1.进程 2.线程 3. 二、对称和非对称 三、常见语言对的支持 总结 前言 本文对的概念做了简要介绍,适合初次接触的小白。 如下图所示: 2.线程 既然已经有了进程的概念,后面为何要引入线程呢?目的是提升操作系统性能,更好的实现并发。 在执行的过程中可以调用其他的,保护上下文切换到其他,之后调用返回恢复到调用的地址继续执行,这个过程类似于多线程的线程的切换。 进程线程的示意图如下所示: 也有自己的缺点,当调用阻塞IO操作的时候,操作系统会让线程进入阻塞状态,这时和其它绑定在该线程之上的都会陷入阻塞而得不到调度。 二、对称和非对称 一般分为对称和非对称两种,定义如下: 非对称(asymmetric coroutines)是跟一个特定的调用者绑定的,让出CPU时,只能让回给调用者。

    1.3K10编辑于 2022-02-22
  • 来自专栏python3

    Python:线程、进程与(2)—

        上一篇博文介绍了Python中线程、进程与的基本概念,通过这几天的学习总结,下面来讲讲Python的threading模块。首先来看看threading模块有哪些方法和类吧。 ? %s" %i         thread_list.append(threading.Thread(target = thread_fun, name = thread_name, args = (2, = threading.Thread(target=worker, args=(readis_ready,"t2"), name='t2') t2.start() print('first of all t1和t2线程开始的时候都阻塞在等待redis服务器启动的地方,一旦主线程确定了redis服务器已经正常启动,那么会触发redis_ready事件,各个工作线程就会去连接redis去做响应的工作。 semaphore = threading.Semaphore(5)#信号量 def func():     if semaphore.acquire():         time.sleep(2)

    72210发布于 2020-01-07
  • 来自专栏厉害了程序员

    python2:yield from 分析

    上一篇python1:yield的使用介绍了: 生成器作为使用时的行为和状态 使用装饰器预激 调用方如何使用生成器对象的 .throw(…) 和 .close() 方法控制 这一篇将介绍 : 终止时如何返回值 yield新句法的用途和语义 让返回值 先看一个例子: 这段代码会返回最终均值的结果,每次激活时不会产出移动平均值,而是最后一次返回。 yield from 的主要功能是打开双向通道,把最外层的调用方与最内层的子生成器连接起来,使两者可以直接发送和产出值,还可以直接传入异常,而不用在中间的添加异常处理的代码。 然后把数据传给之前定义的 averager ,最后生成一个报告。 下一篇,会分析一个使用的经典案例: 仿真编程。这个案例说明了如何使用在单线程中管理并发活动。

    1.1K10发布于 2020-12-25
  • 来自专栏Phoenix的Android之旅

    Kotlin-特殊的阻塞

    阻塞是种特殊的启动方式,一般是用 runBlocking{} 扩起来一段。 首先是父得到执行,然后才是子。 重点是这两段都在同一个线程main里完成。这里就带来一个有趣的问题, runBLocking{}和平时常用的launch有什么区别? 在创建完coroutine后就进入派发流程了,这部分和Kotlin-一个的生命周期中的逻辑比较相似,下面也会讲到。 每个线程都可以起一个独立的阻塞队列。 这个问说明,runBLocking{}这种,它的运行逻辑是先把父放队列里,然后取出来执行,执行完毕再把子入队,再出队子,用同样的方式递归。

    2.9K20发布于 2021-05-17
领券