2015-05-14 36 views
1

我正在启动一个使用系统API的命令(我可以使用这个API与C/C + +)。我通过的命令有时会挂起,因此我想在某个超时后杀死。

目前我使用它为:
是否有可能在C中使用system api启动kill a命令?如果没有任何替代品?

system("COMMAND"); 

我想使用它是这样的:

运行使用系统无关的API命令(我不想用CreateProcess的,因为它仅适用于Windows)如果在'X'分钟后没有退出,则终止该进程。

+0

是您想要执行某些操作的过程吗?如果是这样,为什么它挂起?你可以在那里暂停吗?你想用什么系统api? – Jaques

+0

我正在使用adb命令,adb等待设备。如果没有设备连接/或设备没有出现,该怎么办?我想杀死那个adb wait-for-device命令并给用户一个错误信息。 – Destructor

+1

您可以轻松地编写可移植的头文件来调用系统命令。没有我能想到的跨平台选择。 – Malina

回答

0

我不知道任何使用C语言和C++语言的可移植方法。当你寻求替代品时,我知道这是可能的其他语言。例如在Python中,可以使用subprocess模块。

import subprocess 
cmd = subprocess.Popen("COMMAND", shell = True) 

然后,您可以测试指令是否已经与

if cmd.poll() is not None: 
    # cmd has finished 

结束,你可以杀了它:

cmd.terminate() 

即使你prefere使用C语言,你应该阅读因为它解释了它在内部使用Windows上的CreateProcess和Posix系统上的os.execvp来启动该命令,并且它使用TerminateProcess o n Windows和SIG_TERM上Posix来阻止它。

0

没有标准的跨平台系统API。暗示是他们是系统API!我们实际上是“幸运的”,我们得到了system,但除此之外我们没有得到任何东西。

你可以尝试找到一些第三方抽象。

0

检查以下基于C++线程的Linux尝试。 (未测试)

#include <iostream> 
#include <string> 
#include <thread> 
#include <stdio.h> 

using namespace std; 

// execute system command and get output 
// http://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c 
std::string exec(const char* cmd) { 
    FILE* pipe = popen(cmd, "r"); 
    if (!pipe) return "ERROR"; 
    char buffer[128]; 
    std::string result = ""; 
    while(!feof(pipe)) { 
     if(fgets(buffer, 128, pipe) != NULL) 
      result += buffer; 
    } 
    pclose(pipe); 
    return result; 
} 

void system_task(string& cmd){ 
    exec(cmd.c_str()); 
} 

int main(){ 

    // system commad that takes time 
    string command = "find /"; 

    // run the command in a separate thread 
    std::thread t1(system_task, std::ref(command)); 

    // gives some time for the system task 
    std::this_thread::sleep_for(chrono::milliseconds(200)); 

    // get the process id of the system task 
    string query_command = "pgrep -u $LOGNAME " + command; 

    string process_id = exec(query_command.c_str()); 

    // kill system task 
    cout << "killing process " << process_id << "..." << endl; 
    string kill_command = "kill " + process_id; 
    exec(kill_command.c_str()); 

    if (t1.joinable()) 
     t1.join(); 

    cout << "continue work on main thread" << endl; 

    return 0; 
} 
2

由于system()是特定于平台的调用,就不可能有解决你的问题的一个平台无关的方式。但是,system()是POSIX调用,所以如果它在任何给定平台上受支持,则其余的POSIX API也应该如此。因此,解决您的问题的一种方法是使用fork()kill()

有一个复杂因素,system()调用一个shell,它可能会产生其他进程,并且我认为你想杀死所有的进程,所以一种方法是使用一个进程组。基本思想是使用fork()创建另一个进程,将其放置在其自己的进程组中,并在该特定时间之后不会退出时终止该组。

一个简单的例子 - 程序叉;子进程将其自己的进程组设置为与其进程ID相同,并使用system()产生无限循环。父进程等待10秒钟,然后使用子进程PID的负值杀死进程组。这将杀死分叉进程和该进程的任何子进程(除非他们已经更改了进程组。)

由于父进程位于不同的组中,因此kill()对其没有影响。

#include <unistd.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <stdio.h> 

int main() { 
    pid_t pid; 

    pid = fork(); 
    if(pid == 0) { // child process 
     setpgid(getpid(), getpid()); 
     system("while true ; do echo xx ; sleep 5; done"); 
    } else { // parent process 
     sleep(10); 
     printf("Sleep returned\n"); 
     kill(-pid, SIGKILL); 
     printf("killed process group %d\n", pid); 
    } 
    exit(0); 
} 
相关问题