Answer the question
In order to leave comments, you need to log in
Why can a program crash with exit code: 0xc0000005, STATUS_ACCESS_VIOLATION?
Hello.
I'm trying to implement deserialization into objects from a large json file. I want to do this as quickly as possible, so I decided to read the file in parts, throwing these parts into a vector, and in another thread I use the read data for deserialization, thereby reducing the idle time waiting for the reading from the file to complete.
More briefly: there are two threads, in one thread in a cycle the file is read in chunks and put into a vector, in the other thread this vector is read (.len(), access by index, nothing criminal) .
The problem is that on large files I get a STATUS_ACCESS_VIOLATION error. I realized that it falls out at the moment of appending one vector to another. My hypothesis is that, apparently, there is some kind of race condition, although at first glance, it should not.
main:
mod file_reader;
mod json_consumer;
mod specification;
mod frame;
mod pixel;
use file_reader::read_on_the_fly;
use std::thread;
use std::alloc::handle_alloc_error;
use std::time::{Duration, Instant};
use crate::json_consumer::{deserialize_on_the_fly};
use crate::frame::Frame;
fn main() {
static mut CHAR_BUFFER: Vec<u8> = Vec::new();
static mut FRAME_BUFFER: Vec<frame::Frame> = Vec::new();
static mut IS_FILE_READ: bool = false;
static mut SPECS: specification::Specification = specification::Specification { height: 0, width: 0, frames: 0 };
let reader_handle = thread::spawn(|| unsafe {
let start = Instant::now();
let res = read_on_the_fly("file5_1160_786.json".to_string(), &mut CHAR_BUFFER, &mut IS_FILE_READ);
if res.is_ok() {
println!("\nFILE READ: done, elapsed time is {:?}", start.elapsed().as_secs_f64());
} else {
println!("\nFILE READ: fail");
}
});
let json_handle = thread::spawn(|| unsafe {
let start = Instant::now();
let res = deserialize_on_the_fly(&CHAR_BUFFER, &mut SPECS, &mut FRAME_BUFFER, &mut IS_FILE_READ);
if res.is_ok() {
println!("\nDESERIALIZE: done, elapsed time is {:?}", start.elapsed().as_secs_f64());
} else {
println!("\nDESERIALIZE: fail");
}
});
json_handle.join();
reader_handle.join();
}
use std::io;
use std::io::{Read, BufReader};
use std::fs::File;
use std::str;
use std::thread::sleep;
use std::time::Duration;
pub fn read_on_the_fly(path: String, buffer: &mut Vec<u8>, is_file_read: &mut bool) -> Result<(), io::Error> {
static BUFF_SIZE: usize = 8192;
let mut file = File::open(path)?;
let mut br = BufReader::with_capacity(BUFF_SIZE, file);
let mut tmp_buff = vec![0; BUFF_SIZE];
while br.read(&mut tmp_buff)? != 0 {
buffer.append(&mut tmp_buff.clone());
}
*is_file_read = true;
Ok(())
}
Answer the question
In order to leave comments, you need to log in
For starters, it’s worth rewriting everything without unsafe (it’s not needed here at all)
Instead of incorrect sharing of unique IS_FILE_READ links, use AtomicBool
CHAR_BUFFER also violated the rule of either 1 mut / uniq borrow or many shared borrows, wrap it in Mutex , but better, given the unidirectionality of data, pass through channel
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question