Zig Atomic Operations
Atomic operations are important tools for ensuring data consistency in multithreaded programming. This chapter covers atomic operations and concurrent programming basics in Zig.
Atomic Operations Basics
What are Atomic Operations?
Atomic operations are indivisible operations that guarantee operation integrity in multithreaded environments:
zig
const std = @import("std");
pub fn main() void {
// Normal variable (not thread-safe)
var normal_counter: i32 = 0;
// Atomic variable (thread-safe)
var atomic_counter = std.atomic.Atomic(i32).init(0);
std.debug.print("Normal counter: {}\n", .{normal_counter});
std.debug.print("Atomic counter: {}\n", .{atomic_counter.load(.Monotonic)});
// Atomic operations
_ = atomic_counter.fetchAdd(5, .Monotonic);
std.debug.print("Atomic counter +5: {}\n", .{atomic_counter.load(.Monotonic)});
_ = atomic_counter.fetchSub(2, .Monotonic);
std.debug.print("Atomic counter -2: {}\n", .{atomic_counter.load(.Monotonic)});
}Memory Ordering
Memory ordering defines synchronization and ordering constraints for atomic operations:
zig
const std = @import("std");
pub fn main() void {
var atomic_value = std.atomic.Atomic(i32).init(0);
// Different memory orderings
std.debug.print("Memory ordering example:\n");
// Unordered: weakest memory ordering, only guarantees atomicity
atomic_value.store(10, .Unordered);
const val1 = atomic_value.load(.Unordered);
std.debug.print("Unordered: {}\n", .{val1});
// Monotonic: guarantees operations on same atomic variable are ordered
atomic_value.store(20, .Monotonic);
const val2 = atomic_value.load(.Monotonic);
std.debug.print("Monotonic: {}\n", .{val2});
// Acquire/Release: acquire-release semantics
atomic_value.store(30, .Release);
const val3 = atomic_value.load(.Acquire);
std.debug.print("Acquire/Release: {}\n", .{val3});
// SeqCst: strongest memory ordering, sequential consistency
atomic_value.store(40, .SeqCst);
const val4 = atomic_value.load(.SeqCst);
std.debug.print("SeqCst: {}\n", .{val4});
}Summary
This chapter covered Zig atomic operations in detail:
- ✅ Basic concepts of atomic operations and memory ordering
- ✅ Basic atomic operations: load, store, exchange
- ✅ Atomic arithmetic and bitwise operations
- ✅ Multithreaded programming examples
- ✅ Lock-free data structure implementation
- ✅ Memory barriers and synchronization mechanisms
- ✅ Best practices and performance considerations
Atomic operations are fundamental tools for building high-performance concurrent programs. Proper use of atomic operations can avoid data races and ensure program correctness in multithreaded environments. In the next chapter, we'll learn about Zig's async programming.