我正在啓動一個使用系統API的命令(我可以使用這個API與C/C + +)。我通過的命令有時會掛起,因此我想在某個超時後殺死。
目前我使用它爲:
是否有可能在C中使用system api啓動kill a命令?如果沒有任何替代品?
system("COMMAND");
我想使用它是這樣的:
運行使用系統無關的API命令(我不想用CreateProcess的,因爲它僅適用於Windows)如果在'X'分鐘後沒有退出,則終止該進程。
我正在啓動一個使用系統API的命令(我可以使用這個API與C/C + +)。我通過的命令有時會掛起,因此我想在某個超時後殺死。
目前我使用它爲:
是否有可能在C中使用system api啓動kill a命令?如果沒有任何替代品?
system("COMMAND");
我想使用它是這樣的:
運行使用系統無關的API命令(我不想用CreateProcess的,因爲它僅適用於Windows)如果在'X'分鐘後沒有退出,則終止該進程。
我不知道任何使用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來阻止它。
沒有標準的跨平臺系統API。暗示是他們是系統API!我們實際上是「幸運的」,我們得到了system
,但除此之外我們沒有得到任何東西。
你可以嘗試找到一些第三方抽象。
檢查以下基於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;
}
由於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);
}
是您想要執行某些操作的過程嗎?如果是這樣,爲什麼它掛起?你可以在那裏暫停嗎?你想用什麼系統api? – Jaques
我正在使用adb命令,adb等待設備。如果沒有設備連接/或設備沒有出現,該怎麼辦?我想殺死那個adb wait-for-device命令並給用戶一個錯誤信息。 – Destructor
您可以輕鬆地編寫可移植的頭文件來調用系統命令。沒有我能想到的跨平臺選擇。 – Malina