The following C++ code demonstrates how to safely use an array that is written to by one thread and read from in another thread:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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(); | |
} |
No comments:
Post a Comment