【问题标题】:How to make system() function unblocking?如何使 system() 函数解除阻塞?
【发布时间】:2019-11-08 09:03:06
【问题描述】:

我正在从 android Linux 中的另一个可执行文件调用一个可执行文件。以下是相关代码:

...
int status = system("/system/bin/executable");
...

我的要求是不要等待executable 完成执行。表示我想独立于调用它的可执行文件运行executable

我在互联网上进行了搜索,但没有找到如何使这个系统调用成为非阻塞的。请帮我解决它。

【问题讨论】:

  • 在子进程中使用fork(),然后使用exec()。参见例如“How do fork and exec work?”以及a few other questions here
  • 你可以像在 shell 中那样做。在命令末尾添加&system("/system/bin/executable &");。当然,在这种情况下,您将无法检索可执行文件的状态。
  • @mosvy 使用forkexec,您可以使用wait 检索状态。
  • @mosvy 我同意,如果你想做的是在它的剂量范围内(在后台运行并且收集状态不是)。我有一段时间没有使用 C,但我认为还有其他库抽象了 forkexec,但比 system 更强大。
  • 是的,popen(3)FILE *p = popen("command >/dev/null", "r"); ... do other stuff ...; exit_status = pclose(p); ;-)

标签: linux c


【解决方案1】:

我可以使用以下代码实现非阻塞:

if (fork() == 0)
        {
            char *args[] = {..., NULL};
            char *env[] = {..., NULL};
            if (execve("/system/bin/executable", args, env) == -1)
                print("Error: [%d]", errno);
        }

这里有几件重要的事情:

  • fork() 将创建一个新进程。所以从if(fork() == 0)这行开始,主程序的同一个空间里会运行2个进程。
  • 两个进程从 fork( ) 调用返回执行到主程序的点继续执行..
  • fork() == 0 将在 if 条件下只允许子进程。
  • execve(..) 将用/system/bin/executable 替换子进程程序(它是它通过fork 命令复制的父程序)。
  • execve(..) 运行可执行文件成功则不会返回 else return -1。
  • 如果execve(..) 失败,errno 将填充实际错误。

如果我错了,请纠正我。我希望它会对某人有所帮助。

【讨论】:

  • 你应该收集fork()ed pid,以防你打算稍后等待它。
  • 考虑在 execve() 失败并且您打印了该错误消息后会发生什么。您还必须安装 SIGCHLD 处理程序并等待孩子,以免将其变成僵尸。
  • @Archemar myexecutable 是独立程序,父进程不需要等待。
  • @Archemar 我认为附加 & 后缀在我的情况下很好。因为它将为我处理僵尸进程。感谢@Simon 的解释。
【解决方案2】:

system() 函数,没有错误处理,如下所示:

int system(char const *cmdline)
{
    pid_t pid = fork();
    if(pid == 0)
    {
        char const *argv[] = { "sh", "-c", cmdline, NULL };
        execve("/bin/sh", argv, NULL);
        _exit(1);
    }
    else
    {
        int status;
        waitpid(pid, &status, 0);
        return status;
    }
}

命令本身是由shell解析的,所以可以使用普通的&后缀将命令发送到后台。然后 shell 立即终止,后台程序重新设置为 PID 1(因此您的程序不负责收集僵尸),system() 返回。

【讨论】:

  • 谢谢,我将使用& 后缀,因为父进程不需要照顾子进程。
猜你喜欢
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多