2015-05-14 38 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); 
} 
相關問題