V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kerb15
V2EX  ›  Android

安卓主进程等待多个子进程做完任务有什么优雅的设计模式吗?

  •  
  •   kerb15 · 2020-11-19 17:36:58 +08:00 · 10047 次点击
    这是一个创建于 1466 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个 App 中运行了 4 个进程,包括主进程和 ABC 三个子进程。

    主进程通知 ABC 同时去做一件写文件的任务,当 ABC 都做完时再回来告诉主进程,主进程对生成的文件进行压缩。

    现在想到的笨方法无非就是一个变量去记录 ABC 是否已经完成,比如 000 表示都没完成,111 表示都完成了。

    有没有老哥做过类似的案例,有什么奇思妙想吗?

    31 条回复    2020-12-04 18:08:51 +08:00
    luckyrayyy
        1
    luckyrayyy  
       2020-11-19 17:40:10 +08:00
    这...操作系统和 api 层面都有现成的,你搞些奇技淫巧干啥
    kerb15
        2
    kerb15  
    OP
       2020-11-19 17:43:31 +08:00
    @luckyrayyy 啊,能举个例子吗
    carlclone
        3
    carlclone  
       2020-11-19 17:46:31 +08:00
    信号。。。
    acmore
        4
    acmore  
       2020-11-19 17:46:54 +08:00
    Resource
        5
    Resource  
       2020-11-19 18:10:29 +08:00
    安卓可以用 CompletableFuture 吗?
    jobsofchina
        6
    jobsofchina  
       2020-11-19 18:14:03 +08:00 via Android
    不懂就问,安卓没有 join()吗
    liian2019
        7
    liian2019  
       2020-11-19 18:20:04 +08:00
    CompletionService
    0xZhangKe
        9
    0xZhangKe  
       2020-11-19 19:00:04 +08:00
    RxJava
    tanranran
        10
    tanranran  
       2020-11-19 19:07:00 +08:00   ❤️ 3
    坐等大佬回复,楼上的说实话,都是不看题目的,LZ 说的是进程,不是线程
    kerb15
        11
    kerb15  
    OP
       2020-11-19 19:14:25 +08:00
    @acmore 可以用于进程吗
    kerb15
        12
    kerb15  
    OP
       2020-11-19 19:15:09 +08:00
    @tanranran 哈哈,终于有个看明白的
    gam2046
        13
    gam2046  
       2020-11-19 19:16:50 +08:00
    自己利用 Binder 实现类似 ForkJoinPool 的机制或者共享内存( CPP )是比较低成本的方式。但如果不是因为 OOM,这样的工作,不建议使用多进程这样重量级的方式。
    knowckx
        14
    knowckx  
       2020-11-19 19:20:54 +08:00
    sync.waitgroup 的味道
    hm279
        16
    hm279  
       2020-11-19 19:30:38 +08:00 via Android
    正常人有开三个进程去写一个文件吗?线程吧
    hongch
        17
    hongch  
       2020-11-19 19:32:19 +08:00
    一个 APP 只有一个进程啊,难道是开了多个 service 去写同一个文件?
    又或者是开了多个线程去写同一个文件?
    tanranran
        18
    tanranran  
       2020-11-19 20:35:30 +08:00
    @hongch #17 安卓是可以多个进程的
    hdfg159
        19
    hdfg159  
       2020-11-19 21:59:22 +08:00 via Android
    RxJava 做任务编排
    acmore
        20
    acmore  
       2020-11-19 22:18:31 +08:00
    @kerb15
    @tanranran

    每个进程都用一个线程监控,Process 等待结束之后用 CountDownLatch 通知主进程的主线程。这种方法可以做到 “实时” 监控所有进程的情况。也可以用其他的工具,但我觉得 CountDownLatch 是最直接且直观的。
    ysy950803
        21
    ysy950803  
       2020-11-20 00:20:53 +08:00
    个人认为这个还是很难避免 3 次跨进程通信,说白了还是需要某种计数的。要说最优雅,我觉得 ContentProvider 就能实现,主进程 observe 进行计数,其他进程任务完成后分别写标识。
    此外,也可以利用类似 Handler 这种有消息队列的机制,但是原生 Handler 不是用来跨进程的,不过有人用 Binder 机制实现了跨进程的 Handler,可以谷歌一下。不过利用跨进程 Handler 的话,一样地需要在主进程计数,也避免不了 3 次跨进程通信。
    我能想到的减少进程间通信次数办法,可能还是预估延时机制,你这里是写文件,如果可以提前知道写数据的大小,就能预测一个所有任务都完成的大概时间,到时候就不需要跨进程通信了,主进程在 timeout 之后直接去处理生成的文件,如果发现少了 1 个,就说明还有子进程没完成任务,这时候再降级成跨进程监听吧。这种办法对于及时性要求不高的场景我觉得还是可以的,想法可能不成熟。
    ysy950803
        22
    ysy950803  
       2020-11-20 00:25:20 +08:00
    啊为什么 V 站还不支持编辑,我再补充一下吧。其实利用 ContentProvider 配合数据库就挺好,也是最快的实现方式。如果还使用 Room+LiveData 的话,更方便。
    myCupOfTea
        23
    myCupOfTea  
       2020-11-20 09:16:13 +08:00
    rxjava?
    zpxshl
        24
    zpxshl  
       2020-11-20 09:39:20 +08:00 via Android
    别做这种无聊的事,到线上就会发现,处理边缘 case 比核心代码还多。 子进程挂了咋办?
    okaku
        25
    okaku  
       2020-11-20 10:50:01 +08:00
    子进程蛮独特的,还没接触过需要用进程去提高运算速度的案子
    behanga
        26
    behanga  
       2020-11-20 10:51:08 +08:00
    FileObserver 了解一下
    StrorageBox
        27
    StrorageBox  
       2020-11-20 11:08:35 +08:00
    楼上回复的都什么啊。。。。 你这个情况直接 messager 去做通知,android 里最轻量级的进程间通信了。
    cxxxxx
        28
    cxxxxx  
       2020-11-20 15:03:57 +08:00
    kotlin coroutines async
    b1iy
        29
    b1iy  
       2020-11-20 16:13:40 +08:00
    📢广播.

    我感觉题主有点小题大作。
    RikkaW
        30
    RikkaW  
       2020-11-21 15:34:46 +08:00
    如果 ABC 是 Android 世界的进程用 Binder 是最好的

    但是不管怎么样,主进程里做计数是跑不掉的(
    xierbenq
        31
    xierbenq  
       2020-12-04 18:08:51 +08:00
    建立一个文件夹,子进程做任务时就创建一个文件,做完删掉,主进程监控这个文件夹,不过考虑到子进程各种意外情况死掉,linux flock 也许更合适。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3115 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:12 · PVG 08:12 · LAX 16:12 · JFK 19:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.