//How to safely use an array that is written to by one thread and read from in another thread.
//Requires C++11 or later.
//Şamil Korkmaz, 10.03.2022, public domain.
#include <chrono>
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mx;
std::condition_variable cv;
const size_t arraySize = 1000;
double arr[arraySize];

void writeArray() {
	size_t counter = 0;
	while (1) {
		auto currentTime = std::chrono::steady_clock::now();
		auto nextTime = currentTime + std::chrono::milliseconds(1);
		//printf("writeArray, counter = %d\n", counter);
		{ //critical section
			std::unique_lock<std::mutex> lock(mx);
			for (size_t i = 0; i < arraySize; i++) {
				arr[i] = counter;
			}
		} //lock is automatically released here
		cv.notify_all(); //let other threads to get lock
		counter++;
		std::this_thread::sleep_until(nextTime);
	}
}

void readArray() {
	while (1) {
		auto currentTime = std::chrono::steady_clock::now();
		auto nextTime = currentTime + std::chrono::milliseconds(1);
		double arrStart;
		double arrEnd;
		{ //critical section
			std::unique_lock<std::mutex> lock(mx);
			cv.wait(lock); //wait for writeArray to finish
			arrStart = arr[0];
			arrEnd = arr[arraySize - 1];
		} //lock is automatically released here
		auto arrDiff = arrEnd - arrStart;
		printf("* readArray, arrStart = %1.0f, arrEnd = %1.0f, arrDiff = %1.1f\n", arrStart, arrEnd, arrDiff);
		if (arrDiff < 0) //happens when the end of array is lagging behing beginning of array. You trigger it by commenting out the lock line above
		{
			printf("End of array lagging behind beginning of array! arrDiff = %1.1f < 0\n", arrDiff);
			std::cout << "Press enter..." << std::endl;
			std::cin.get();
			exit(1);
		}
		std::this_thread::sleep_until(nextTime);
	}
}

int main() {

	std::thread worker1(writeArray);
	std::thread worker2(readArray);
	
	worker1.join();
	worker2.join();

	std::cout << "Press enter..." << std::endl;
	std::cin.get();
}