如何在C中终止system()调用

时间:2016-05-23 12:01:12

标签: c linux shell

如何在同一源代码中杀死system()进程(挂起)是我的问题。执行此操作的替代方法是将SIGTERM或SIGKILL从另一个终端/命令行发送到该pid,但前一个选项是我正在寻找的。因为我们知道system()调用将阻塞所有信号,直到它完成/退出,因此我找不到任何解决方案.Below代码将给你更清晰。还让我指定df(hp-ux中的bdf)shell命令挂起(等待nfs /网络资源),因此我希望在7秒后终止它。 要添加,我的代码服务的目的是在7秒后出现,但进程bdf卡在后台的某个地方,将自己的父ID作为init(1)。

#include<stdio.h>
#include<stdlib.h>
#include<sys/signal.h>

#define endl printf("\n")
pid_t child_pid;


void sig_handler(int sig)
{
    endl;
    printf(" Exiting after 7 seconds ");
    endl;
    signal(SIGALRM, SIG_DFL);
    void sig_handler(int sig);    /// reestablishing signal
}

int main(int argc, char * argv[])
{
    pid_t pid;

    pid=fork();

    if(pid<0)
    {
        perror(" cannot create process/child");
        endl;
    }

    if(pid==0)
    {
        child_pid=getpid();
        printf(" Executing bdf command with process id %d",child_pid);
        endl;
        signal(SIGALRM,sig_handler);
        alarm(7);
        system("bdf");
    }
    if(pid>0)
    {
        sleep(7);
        exit(0);
    }

}

3 个答案:

答案 0 :(得分:5)

不要控制system,在您的特定情况下甚至不要使用它。

阅读Advanced Linux Programming(免费提供,here!)然后使用较低级别的系统调用,例如fork(2)execve(2)waitpid(2)(也许pipe(2)&amp; dup2(2)&amp; poll(2),特别是如果bdf是一个给出一些有趣输出的命令)等等......那本ALP书有几章可以解释你怎么做。

请记住,在system(3)下,只需使用/bin/sh选项对-c程序执行操作即可。你也可以明确地做同样的事情(但是你最好在你的程序本身中实现任何所需的globbing;显然在你的情况下你不需要那个&amp;你可以分叉execvp(3) "bdf"程序直接)。

仔细阅读signal(7)并注意您的程序错误(具有未定义的行为),因为它从信号处理程序内部调用printf。这是禁止的(因为printf不是 async-signal-safe 函数)。

附加物

在新编辑的问题中,尝试替换

if(pid==0) {
    child_pid=getpid();
    printf(" Executing bdf command with process id %d",child_pid);
    endl;
    signal(SIGALRM,sig_handler);
    alarm(7);
    system("bdf");
}

if(pid==0) {
    child_pid=getpid();
    printf(" Executing bdf command with process id %d\n",
           child_pid);
    fflush(NULL);
    signal(SIGALRM,sig_handler);
    alarm(7);
    if (execlp("bdf","bdf", NULL)) {
      perror("exec bdf");
      exit(EXIT_FAILURE);
    }
}

然后使用strace(1)(使用-f)来了解正在发生的事情。

但是你需要花几天时间阅读好书(例如ALP关于Linux编程。您无法避免了解过程如何在Unix / Linux和POSIX系统上运行。

答案 1 :(得分:0)

@Mark:这是新代码

#define endl printf("\n")
pid_t child_pid;
int statloc;

void sig_handler(int sig)

{
endl;
printf(" Exiting after 7 seconds ");
endl;
signal(SIGALRM, SIG_DFL);
}
int main()

{
pid_t pid;
pid=fork();
if(pid<0)
{
perror(" child error");
endl;
}

if(pid==0)
{
char * arg[]= {"bdf", NULL } ;
child_pid=getpid();
printf(" Executing bdf command with process id %d",child_pid);
endl;
signal(SIGALRM,sig_handler);
alarm(4);
execv("/usr/bin/bdf",arg);

}

if(pid>0)
{
waitpid(pid,&statloc,0);
exit(0);
}

}

答案 2 :(得分:0)

使用fork和exec获取pid,存储它。然后你可以随时杀死它。

如果您需要pid,请不要使用系统。

系统只应用于自然终止的进程。

考虑系统(&#34;流程&amp;&#34;) 这将允许系统在后台运行,同时允许父级继续在当前空间中运行。