This question comes mainly from curiosity. I'm not quite sure how to phrase it best. Especially in a title. But I'm wondering if say you have one thread writing to a variable of an essentially primitive type and one thread reading them at the same time if there's any likelihood of the read happening while the variable is half written causing either weird values or undefined behavior.
Take something like a value of 8 bits from 00010101 to 11101000.
I'm imagining if say 4 bits are written while we try to read it the result could be something like
11100101
To play around i made this small sample rust. It passed without making garbage. Printing at first a bunch of lines stating "String = Hello!" and second "String = Hi!" without weirdness or issues. I kind of half-expected something like "String = #æé¼¨A" or a segfault.
use std::thread::{self, JoinHandle, sleep};
const HELLO: &str = "Hello!";
const HI: &str = "Hi!";
struct ExemptSyncStringSlice<'a>(&'a str);
unsafe impl Sync for ExemptSyncStringSlice<'_> {}
fn print_ptr(pointer: *const ExemptSyncStringSlice)
{
for _ in 1..500
{
unsafe
{
println!("String = {}", (*pointer).0);
}
}
}
fn main()
{
static mut DESYNC_POINTER: ExemptSyncStringSlice = ExemptSyncStringSlice(HELLO);
let join_handle: JoinHandle<()> = thread::spawn
(
|| {
print_ptr(&raw const DESYNC_POINTER);
}
);
sleep(time::Duration::from_millis(1));
unsafe { DESYNC_POINTER.0 = HI; }
join_handle.join().unwrap();
}
In general, yes, it's possible to end up with half-written variables -- mutexes (and/or other synchronization primitives) are used to avoid that kind of problem.
Whether you can encounter it in practice depends on the specific programming language, CPU, compiler, and actual instructions involved. Some operations that seem like they should be atomic from the perspective of a high level language are actually implemented as multiple machine code instructions and the thread could be interrupted between them, causing problems, unless steps are deliberately taken to avoid issues with concurrency.
I have minimal experience with Rust, so I'm not sure how bad the footguns you can run into with
unsafeare there specifically, but you can definitely blow your leg off in C/C++...save