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

任务暂停怎么实现?

  •  
  •   smallpython · 2019-07-01 18:11:45 +08:00 · 2988 次点击
    这是一个创建于 1979 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有没有好的思路?比如下载一个文件,暂停是怎么做的?
    执行一个扫描任务,暂停是怎么做的?
    游戏中的暂停是怎么做的?
    第 1 条附言  ·  2019-07-02 09:29:09 +08:00
    还有就是虚拟机的暂停是什么原理?
    20 条回复    2019-07-08 11:50:01 +08:00
    janxin
        1
    janxin  
       2019-07-01 18:24:51 +08:00
    下载暂停就是不下了...不读取数据不就行了。暂停容易,比较麻烦的是继续
    扫描也是一样的
    dabang007
        2
    dabang007  
       2019-07-01 18:29:10 +08:00
    一个参考模型:while(1) {
    if(flag) {dothething}
    else {sleep(1)}
    }
    azh7138m
        3
    azh7138m  
       2019-07-01 18:32:53 +08:00
    下载一个文件,暂停是怎么做的?

    这个不太一样,对于普通的 http 场景,range 请求本身就是分块下载的,剩余的分块不开始下载就好了。p2p 协议基本都是分块下载的,也是如此。

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
    qq316107934
        4
    qq316107934  
       2019-07-01 18:38:59 +08:00
    @dabang007 #2 这种模型比较简单粗暴,简单的需求可以满足,如果中间需要终端程序再恢复会出问题。如果需要做到断点恢复的话需要设置一个 cursor 来指示进度到哪了,点击恢复的时候从上次的进度继续,下载同 @azh7138m。 如果是扫描任务的话就先把全盘的文件列表拿出来,然后再把剩余的文件列表存起来。 游戏的暂停倒是更类似于中断,可以简化为 @dabang007 的原理。
    txy3000
        5
    txy3000  
       2019-07-01 18:39:49 +08:00 via Android
    暂停倒是简单 要续上你得保存当前的状态信息
    就跟中断调用一样 PC 压栈 寄存器压栈 PC 跳转中断调用表 执行完后 寄存器出栈 PC 出栈赋值 继续中断前的干 这些原理都是相通的
    http header 有 range 具体可以 Google 如何实现的都有
    sunmker
        6
    sunmker  
       2019-07-01 23:51:34 +08:00 via Android
    楼主可能相问,中断如何保存现场?
    smallpython
        7
    smallpython  
    OP
       2019-07-02 09:24:40 +08:00
    @sunmker 是的
    smallpython
        8
    smallpython  
    OP
       2019-07-02 09:26:11 +08:00
    我理解的暂停就是内存和这个任务相关的数据都不发生变化,然后一点继续就再让 cpu 继续处理这些数据
    smallpython
        9
    smallpython  
    OP
       2019-07-02 09:28:28 +08:00
    @dabang007 那如果在你 dothething 的时候点击暂停,它还是会继续执行,直到下一个 if 判断
    Todd_Leo
        10
    Todd_Leo  
       2019-07-02 11:09:09 +08:00
    我的产品经理给我说需要实现一个 Spark 计算任务的暂停和恢复 :)
    zivyou
        11
    zivyou  
       2019-07-02 11:20:43 +08:00
    感觉可以自己用一些数据保存好当前的进度状态,之后再让父进程把当前的线程挂起。恢复的时候,父进程用之前保存的进度状态数据恢复出执行线程。
    smallpython
        12
    smallpython  
    OP
       2019-07-02 11:41:08 +08:00
    @Todd_Leo 就是算到一半,暂停,然后还能继续算,是吗?
    smallpython
        13
    smallpython  
    OP
       2019-07-02 11:42:56 +08:00
    @zivyou 是的,挂起应该就是暂停,但是我不知道怎么让一个线程被挂起.
    而且正常情况下,一个任务应该是一个进程
    能不能让操作系统把这个进程挂起?
    smallpython
        14
    smallpython  
    OP
       2019-07-02 11:45:31 +08:00
    @qq316107934 我的理解是 cpu 同时只能操作一个进程(单核),那么此时其他的进程不就是暂停的状态吗?能不能控制 cpu 的这种行为?
    hyq
        15
    hyq  
       2019-07-02 12:37:27 +08:00
    虚拟机的暂停不知道怎么实现的,但是下载的暂停很简单
    while(running)
    {
    if (is_pause)
    {
    sleep(1);
    continue;
    }
    read_some_bytes();
    }

    游戏的暂停也比较简单,因为游戏一般都是有个主循环,主循环里面执行各种逻辑,只要不执行这些逻辑,就达到了暂停的目的

    Game::loop()
    {
    if (!is_pause)
    {
    logic.loop();
    animation.loop();
    ....
    }
    }
    enaxm
        16
    enaxm  
       2019-07-02 13:02:21 +08:00
    @Todd_Leo #10 想知道后续 :p
    zivyou
        17
    zivyou  
       2019-07-02 13:38:26 +08:00
    @smallpython 如果这些任务进程是自己的子进程的话,应该可以通过发送 SIGSTOP/SIGCONT 来挂起 /唤醒 任务进程。如果不是的话,就直接通过系统的 kill 指令来做就好了。
    Todd_Leo
        18
    Todd_Leo  
       2019-07-02 14:49:53 +08:00
    @smallpython 是的
    @enaxm 被我喷回去了,只能杀掉任务取消,然后重新跑
    SmiteChow
        19
    SmiteChow  
       2019-07-08 11:01:03 +08:00
    我想你 需要的是 CRIU
    smallpython
        20
    smallpython  
    OP
       2019-07-08 11:50:01 +08:00
    @SmiteChow 感谢大神,又扩展视野了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2649 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 11:46 · PVG 19:46 · LAX 03:46 · JFK 06:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.