Zig 如何創建子進程
在 C 裏面,fork/exec 是一套典型的創建新進程的方式,Zig 裏面對此進行的一定封裝,提供了 std.process.Child 結構來簡化這一流程,下面看一示例:
const std = @import("std");
const print = std.debug.print;
const Child = std.process.Child;
const ArrayList = std.ArrayList;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer if (gpa.deinit() != .ok) @panic("leak");
const allocator = gpa.allocator();
const argv = [_][]const u8{
"echo",
"-n",
"hello",
"world",
};
// By default, child will inherit stdout & stderr from its parents,
// this usually means that child's output will be printed to terminal.
// Here we change them to pipe and collect into `ArrayList`.
var child = Child.init(&argv, allocator);
child.stdout_behavior = .Pipe;
child.stderr_behavior = .Pipe;
var stdout = ArrayList(u8).init(allocator);
var stderr = ArrayList(u8).init(allocator);
defer {
stdout.deinit();
stderr.deinit();
}
try child.spawn();
try child.collectOutput(&stdout, &stderr, 1024);
const term = try child.wait();
try std.testing.expectEqual(term.Exited, 0);
try std.testing.expectEqualStrings("hello world", stdout.items);
try std.testing.expectEqualStrings("", stderr.items);
}
在使用Child.init
初始化後,爲了能夠捕獲子進程的標準輸出與錯誤輸出,需要修改 behavior 爲.Pipe
,這樣在 spawn 時,Zig 就會給 stdout、stderr 這兩個文件創建兩個管道,之後再調用 collectOutput 這個方法來收集他們就可以了,這個方法內會調用 poll[1] 來對 stdout、stderr 這兩個文件同時監聽讀請求,直到這兩個文件都已經返回 EOF 爲止。
加入我們
Zig 中文社區是一個開放的組織,我們致力於推廣 Zig 在中文羣體中的使用,有多種方式可以參與進來:
-
供稿,分享 [2] 自己使用 Zig 的心得
-
改進 ZigCC 組織下的開源項目 [3]
-
加入微信羣 [4]
參考資料
[1]
poll:https://man7.org/linux/man-pages/man2/poll.2.html
[2]
供稿,分享:https://ziglang.cc/contributing
[3]
開源項目:https://ask.ziglang.cc/github
[4]
微信羣:https://ask.ziglang.cc/weixin
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/1lpQB1_urRE-SJfTZcv-0Q