Peter-Barrow/shared-memory-zig
Unified interface to shared memory on Linux, macOS and Windows
aa24df42183ad415d10bc0a33e6238c437fc0f59
7b434a47c2b85f395d8e5a6dca47af6a74422521
Overview
This library implements a unified interface to shared memory on Linux, macOS and Windows
Add the following to you build.zig.zon
, replacing the url with the latest archive, for example https://github.com/Peter-Barrow/shared-memory-zig/archive/699c748fbb143733183760cc7e83ded098eac6d1.zip
and then replacing the hash with the latest commit hash.
.{
.name = "my-project",
.version = "0.0.0",
.dependencies = .{
.shared_memory = .{
.url = "",
.hash = "",
},
},
}
Or alternatively run:
zig fetch --save git+https://github.com/Peter-Barrow/shared-memory-zig.git
Add the following to your build.zig
const shared_memory = b.dependency("shared_memory", .{}).module("shared_memory");
const exe = b.addExecutable(...);
// This adds the shared-memory-zig module to the executable which can then be imported with `@import("shared-memory-zig")`
exe.root_module.addImport("shared-memory-zig", shared_memory);
For compatibility with Windows this requires zigwin32
This codebase also uses the known-folders library to get the runtime directory on Linux and FreeBSD when using the memfd
backend.
const shmem = @import("shared_memory");
const TestStruct = struct {
id: i32,
float: f64,
string: [20]u8,
};
const shm_name = "/test_struct_with_string";
var shm: SharedStruct = try SharedStruct.create(shm_name, alloca);
defer shm.close();
shm.data.* = .{ .x = 42, .y = 3.14 };
// Open the shared memory in another "process"
var shm2 = try SharedStruct.open(shm_name, alloca);
defer shm2.close();
try std.testing.expectEqual(@as(i32, 42), shm2.data.x);
try std.testing.expectApproxEqAbs(@as(f64, 3.14), shm2.data.y, 0.001);
const shmem = @import("shared_memory");
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloca = switch (tag) {
.linux, .freebsd => gpa.allocator(),
else => null,
};
const array_size = 20;
var expected = [_]i32{0} ** array_size;
for (0..array_size) |i| {
expected[i] = @intCast(i * 2);
}
const shm_name = "/test_array";
const SharedI32 = SharedMemory([array_size]i32);
var shm: SharedI32 = try SharedI32.create(shm_name, alloca);
defer shm.close();
for (shm.data, 0..) |*item, i| {
item.* = @intCast(i * 2);
}
// Open the shared memory in another "process"
var shm2 = try SharedI32.open(shm_name, alloca);
defer shm2.close();
for (shm2.data, 0..) |item, i| {
try std.testing.expectEqual(@as(i32, @intCast(i * 2)), item);
}
try std.testing.expectEqualSlices(i32, &expected, shm2.data);
}
const shmem = @import("shared_memory");
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloca = switch (tag) {
.linux, .freebsd => gpa.allocator(),
else => null,
};
const array_size = 20;
var expected = [_]i32{0} ** array_size;
for (0..array_size) |i| {
expected[i] = @intCast(i * 2);
}
const shm_name = "/test_array";
const SharedI32 = SharedMemory([]i32);
var shm: SharedI32 = try SharedI32.createWithLength(shm_name, array_size, alloca);
defer shm.close();
for (shm.data, 0..) |*item, i| {
item.* = @intCast(i * 2);
}
// Open the shared memory in another "process"
var shm2 = try SharedI32.open(shm_name, alloca);
defer shm2.close();
for (shm2.data, 0..) |item, i| {
try std.testing.expectEqual(@as(i32, @intCast(i * 2)), item);
}
try std.testing.expectEqualSlices(i32, &expected, shm2.data);