任务暂停怎么实现?

2019-07-01 18:11:45 +08:00
 smallpython
有没有好的思路?比如下载一个文件,暂停是怎么做的?
执行一个扫描任务,暂停是怎么做的?
游戏中的暂停是怎么做的?
2878 次点击
所在节点    程序员
20 条回复
janxin
2019-07-01 18:24:51 +08:00
下载暂停就是不下了...不读取数据不就行了。暂停容易,比较麻烦的是继续
扫描也是一样的
dabang007
2019-07-01 18:29:10 +08:00
一个参考模型:while(1) {
if(flag) {dothething}
else {sleep(1)}
}
azh7138m
2019-07-01 18:32:53 +08:00
下载一个文件,暂停是怎么做的?

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

https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
qq316107934
2019-07-01 18:38:59 +08:00
@dabang007 #2 这种模型比较简单粗暴,简单的需求可以满足,如果中间需要终端程序再恢复会出问题。如果需要做到断点恢复的话需要设置一个 cursor 来指示进度到哪了,点击恢复的时候从上次的进度继续,下载同 @azh7138m。 如果是扫描任务的话就先把全盘的文件列表拿出来,然后再把剩余的文件列表存起来。 游戏的暂停倒是更类似于中断,可以简化为 @dabang007 的原理。
txy3000
2019-07-01 18:39:49 +08:00
暂停倒是简单 要续上你得保存当前的状态信息
就跟中断调用一样 PC 压栈 寄存器压栈 PC 跳转中断调用表 执行完后 寄存器出栈 PC 出栈赋值 继续中断前的干 这些原理都是相通的
http header 有 range 具体可以 Google 如何实现的都有
sunmker
2019-07-01 23:51:34 +08:00
楼主可能相问,中断如何保存现场?
smallpython
2019-07-02 09:24:40 +08:00
@sunmker 是的
smallpython
2019-07-02 09:26:11 +08:00
我理解的暂停就是内存和这个任务相关的数据都不发生变化,然后一点继续就再让 cpu 继续处理这些数据
smallpython
2019-07-02 09:28:28 +08:00
@dabang007 那如果在你 dothething 的时候点击暂停,它还是会继续执行,直到下一个 if 判断
Todd_Leo
2019-07-02 11:09:09 +08:00
我的产品经理给我说需要实现一个 Spark 计算任务的暂停和恢复 :)
zivyou
2019-07-02 11:20:43 +08:00
感觉可以自己用一些数据保存好当前的进度状态,之后再让父进程把当前的线程挂起。恢复的时候,父进程用之前保存的进度状态数据恢复出执行线程。
smallpython
2019-07-02 11:41:08 +08:00
@Todd_Leo 就是算到一半,暂停,然后还能继续算,是吗?
smallpython
2019-07-02 11:42:56 +08:00
@zivyou 是的,挂起应该就是暂停,但是我不知道怎么让一个线程被挂起.
而且正常情况下,一个任务应该是一个进程
能不能让操作系统把这个进程挂起?
smallpython
2019-07-02 11:45:31 +08:00
@qq316107934 我的理解是 cpu 同时只能操作一个进程(单核),那么此时其他的进程不就是暂停的状态吗?能不能控制 cpu 的这种行为?
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
2019-07-02 13:02:21 +08:00
@Todd_Leo #10 想知道后续 :p
zivyou
2019-07-02 13:38:26 +08:00
@smallpython 如果这些任务进程是自己的子进程的话,应该可以通过发送 SIGSTOP/SIGCONT 来挂起 /唤醒 任务进程。如果不是的话,就直接通过系统的 kill 指令来做就好了。
Todd_Leo
2019-07-02 14:49:53 +08:00
@smallpython 是的
@enaxm 被我喷回去了,只能杀掉任务取消,然后重新跑
SmiteChow
2019-07-08 11:01:03 +08:00
我想你 需要的是 CRIU
smallpython
2019-07-08 11:50:01 +08:00
@SmiteChow 感谢大神,又扩展视野了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/579042

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX