【问题标题】:C++ pause/resume system on large operation大型操作上的 C++ 暂停/恢复系统
【发布时间】:2019-01-18 20:27:54
【问题描述】:

我有一个 C++ 程序,它加载一个几百万行的文件并开始处理,同样的操作是由一个 php 脚本完成的,但是为了减少执行时间我切换到了 C++。

在旧脚本中,我检查了“暂停”文件夹中是否存在具有当前操作ID的文件,该文件为空这只是为了检查是否请求暂停,然后脚本在每5次迭代后检查如果有这样的文件,如果有它卡在一个空循环上,直到文件被删除(a.k.a resume):

foreach($lines as $line)
    {
        $isFinished = $index >= $countData - 1;
        if($index % 5 == 0)
        {
            do
            {
                $isPaused = file_exists("/home/pauses/".$content->{'drop-id'});
            }while($isPaused);
        }
        // Starts processing the line here 
}

但由于磁盘访问速度相对较慢,我不想遵循相同的方法,所以我在想一些模拟这个的命令:

$ kill cpp_program // C++ program returns the last index checked e.g: 37710
$ ./main 37710
$ // cpp_program escapes the first 37709 lines and continues its job

您如何看待这种方法?可行吗?它不耗时吗?有没有更好的方法? 谢谢

编辑:澄清,因为这似乎有点模棱两可,这个任务在后台运行,有另一个应用程序启动这个,我希望能够从管理应用程序(通过 Linux 命令)发送命令到后台任务暂停/恢复。

【问题讨论】:

  • 你可以给你的进程发送一个信号,在收到这个信号后,它可以进入无限睡眠——下一个信号会唤醒它。这是解决该问题的技术含量相对较低的解决方案之一。
  • @SergeyA 知道如何在不“杀死”进程的情况下向进程发送信号吗?我见过的所有示例都使用 kill 命令
  • 为什么要暂停/恢复?谁用你以前的方法创建/删除了文件?
  • 您是尝试从同一进程内还是从外部限制任务?我不清楚。
  • 尝试 SIGSTOP/SIGCONT。

标签: c++ performance resume pause


【解决方案1】:

遗憾的是,在大多数操作系统上,跳转到文本文件的第 37710 行需要读取所有 37710 行。

在大多数操作系统上,文本文件是带有换行约定的二进制文件。但是操作系统不会缓存换行符的位置。

所以要找到换行符,你必须读取每个字节。

如果您的程序保存了它到达的文件的字节偏移量,它可以寻找到那个位置。

您可以在关闭时将程序的状态保存到某个配置文件中,并在再次启动时将其设置为默认恢复。这将需要捕获您用于关闭的信号,让您的主逻辑注意到信号标志被设置,然后干净地关闭。这是一个非常 C 式的操作。


现在,使程序可远程控制的另一种传统方法是让它侦听 TCP 端口(和/或标准输入)并在那里执行命令行命令。

为此,您需要编写一个REPL 组件,然后将其连接到任何输入和输出。

要么在处理文件之间以协程的方式执行 REPL,要么生成一个单独的线程来执行 REPL 并让它与处理线程异步通信。

但是,这可能超出您的能力范围。每一步(编写一个 REPL 系统,让它不阻塞主要工作,响应命令,然后将其连接到 TCP 端口)都需要你付出一些努力和学习。

【讨论】:

  • 我相信信号是我的必经之路,正如你所说,REPL 需要一些学习努力,而且我没有太多时间在这个项目上,谢谢 :)
  • 把事情做好总是需要时间真是太可惜了。
猜你喜欢
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
  • 2016-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多