【问题标题】:Job control in linux with C使用 C 语言在 linux 中进行作业控制
【发布时间】:2011-09-28 07:08:15
【问题描述】:

我所知道的:

当一个进程正在运行时,我可以按“CTRL + Z”并暂停它。使用bgfg 命令,我可以在“后台”或“前台”模式下运行它。

我在问什么:

有没有办法暂停一个进程,让它在 C 中在后台或前台运行?

编辑: 我有进程ID。例如,我想将该进程发送到后台。

【问题讨论】:

  • 可能会发送 SIGSTP 信号,但是我不知道您是否可以通过编程方式将其恢复为 bg 或 fg 相对于运行该进程的 shell 进程(我认为您不能,但我可能错了)。您可以尝试system,但我不确定system("bg 1") 之类的东西是否有效,因为该作业对于正在运行的 shell 来说是“本地”的,并且 afaik 系统可以执行自己的“shell 解释器”实例,或者其他任何东西

标签: c linux process job-control


【解决方案1】:

您可以使用kill(pid, SIGSTOP) 将其挂起,但使其成为前台或后台是运行它的 shell 的一项功能,因为它实际影响的是 shell 是立即显示提示(并接受新命令)还是等待直到作业退出。除非 shell 提供 RPC 接口(如 DBus),否则没有干净的方法来更改等待/不等待标志。

【讨论】:

  • @geocar:在 shell 的内存空间中查找标志,然后通过调试 API 更改它,不符合“干净方式”IMO。
【解决方案2】:

Linux 进程通常可以通过向其发送 SIGSTOP 信号来暂停或通过向其发送 SIGCONT 信号来恢复。在 C 语言中,

#include <signal.h>

kill(pid, SIGSTOP);
kill(pid, SIGCONT);

一个进程可以使用pause()暂停自己。

“前景”和“背景”模式不是进程的属性。它们是父 shell 进程如何与它们交互的属性: 在 fg 模式下,shell 的输入被传递给子进程,shell 等待子进程退出。在 bg 模式下,shell 自己接受输入,并与子进程并行运行。

【讨论】:

  • 感谢#include &lt;signal.h&gt;,没有其他人拥有它。
【解决方案3】:

你不能。 bgfg 是 shell 命令,不能从 C 调用任意 shell 中的命令。

【讨论】:

    【解决方案4】:

    通常的方法是分叉出一个子进程,然后退出父进程。 See this for a simple example.

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #define EXIT_SUCCESS 0
    #define EXIT_FAILURE 1
    
    static void daemonize(void)
    {
        pid_t pid, sid;
    
        /* already a daemon */
        if ( getppid() == 1 ) return;
    
        /* Fork off the parent process */
        pid = fork();
        if (pid < 0) 
        {
            exit(EXIT_FAILURE);
        }
        /* If we got a good PID, then we can exit the parent process. */
        if (pid > 0) 
        {
            exit(EXIT_SUCCESS);
        }
    
        /* At this point we are executing as the child process */
    
        /* Change the file mode mask */
        umask(0);
    
        /* Create a new SID for the child process */
        sid = setsid();
        if (sid < 0) 
        {
            exit(EXIT_FAILURE);
        }
    
    
        /* Change the current working directory.  This prevents the current
           directory from being locked; hence not being able to remove it. */
        if ((chdir("/")) < 0) 
        {
            exit(EXIT_FAILURE);
        }
    
        /* Redirect standard files to /dev/null */
        freopen( "/dev/null", "r", stdin);
        freopen( "/dev/null", "w", stdout);
        freopen( "/dev/null", "w", stderr);
    }
    
    int main( int argc, char *argv[] ) 
    {
        daemonize();
    
        /* Now we are a daemon -- do the work for which we were paid */
    
        return 0;  
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      • 2011-11-04
      • 2014-08-11
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 2010-12-10
      相关资源
      最近更新 更多