如何使 vala 子进程超时?
How to timeout a vala Subprocess?
我正在尝试 运行 GLib.Subprocess 中的可执行文件并提取其结果。但是,它可能是一个无限循环,永远不会结束。所以,我希望 Subprocess 在 1 秒后结束。这是我尝试过的:
string executable = "/path/to/executable";
string input = "some_input";
uint timeout_id = 0;
...
...
try {
string output_string;
var subp = new GLib.Subprocess.newv ({executable}, SubprocessFlags.STDIN_PIPE | SubprocessFlags.STDOUT_PIPE);
timeout_id = GLib.Timeout.add (1, () => {
subp.force_exit ();
source_remove ();
return false;
});
subp.communicate_utf8 (input, null, out output_string, null);
} catch (GLib.Error e) {
print ("Error: %s\n", e.message);
}
...
...
void source_remove () {
if (timeout_id > 0) {
Source.remove (timeout_id);
timeout_id = 0;
}
}
我也尝试过使用 {"timeout", "1", executable}
,但如果可执行文件是无限循环,它不会停止。
问题出在这一行:
subp.communicate_utf8 (input, null, out output_string, null);
您正在使用同步 GSubProcess.communicate_utf8()
call, which will block until the process is terminated. Since your timeout callback is also called in the mainloop (which means the same thread), it won't be called either. To prevent this, you should use the asynchronous variant, GSubProcess.communicate_utf8_async()
.
注意:您不需要在超时回调中调用 source_remove()
:GSource 将通过返回 false 自动删除。
我正在尝试 运行 GLib.Subprocess 中的可执行文件并提取其结果。但是,它可能是一个无限循环,永远不会结束。所以,我希望 Subprocess 在 1 秒后结束。这是我尝试过的:
string executable = "/path/to/executable";
string input = "some_input";
uint timeout_id = 0;
...
...
try {
string output_string;
var subp = new GLib.Subprocess.newv ({executable}, SubprocessFlags.STDIN_PIPE | SubprocessFlags.STDOUT_PIPE);
timeout_id = GLib.Timeout.add (1, () => {
subp.force_exit ();
source_remove ();
return false;
});
subp.communicate_utf8 (input, null, out output_string, null);
} catch (GLib.Error e) {
print ("Error: %s\n", e.message);
}
...
...
void source_remove () {
if (timeout_id > 0) {
Source.remove (timeout_id);
timeout_id = 0;
}
}
我也尝试过使用 {"timeout", "1", executable}
,但如果可执行文件是无限循环,它不会停止。
问题出在这一行:
subp.communicate_utf8 (input, null, out output_string, null);
您正在使用同步 GSubProcess.communicate_utf8()
call, which will block until the process is terminated. Since your timeout callback is also called in the mainloop (which means the same thread), it won't be called either. To prevent this, you should use the asynchronous variant, GSubProcess.communicate_utf8_async()
.
注意:您不需要在超时回调中调用 source_remove()
:GSource 将通过返回 false 自动删除。