我正在启动一个使用系统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