Atomic updates: Difference between revisions
Content added Content deleted
No edit summary |
|||
Line 396: | Line 396: | ||
752 490 385 2118 1503 508 384 509 1110 2241 Sum: 10000 |
752 490 385 2118 1503 508 384 509 1110 2241 Sum: 10000 |
||
752 823 385 2118 1544 508 10 509 1110 2241 Sum: 10000</lang> |
752 823 385 2118 1544 508 10 509 1110 2241 Sum: 10000</lang> |
||
=={{header|C++}}== |
|||
{{trans|C}} |
|||
{{works with|C++11}} |
|||
<lang cpp>#include <algorithm> |
|||
#include <array> |
|||
#include <chrono> |
|||
#include <iomanip> |
|||
#include <iostream> |
|||
#include <mutex> |
|||
#include <random> |
|||
#include <thread> |
|||
using namespace std; |
|||
constexpr int bucket_count = 15; |
|||
void equalizer(array<int, bucket_count>& buckets, |
|||
array<mutex, bucket_count>& bucket_mutex) { |
|||
random_device rd; |
|||
mt19937 gen(rd()); |
|||
uniform_int_distribution<> dist_bucket(0, bucket_count - 1); |
|||
while (true) { |
|||
int from = dist_bucket(gen); |
|||
int to = dist_bucket(gen); |
|||
if (from != to) { |
|||
lock_guard<mutex> lock_first(bucket_mutex[min(from, to)]); |
|||
lock_guard<mutex> lock_second(bucket_mutex[max(from, to)]); |
|||
int diff = buckets[from] - buckets[to]; |
|||
int amount = abs(diff / 2); |
|||
if (diff < 0) { |
|||
swap(from, to); |
|||
} |
|||
buckets[from] -= amount; |
|||
buckets[to] += amount; |
|||
} |
|||
} |
|||
} |
|||
void randomizer(array<int, bucket_count>& buckets, |
|||
array<mutex, bucket_count>& bucket_mutex) { |
|||
random_device rd; |
|||
mt19937 gen(rd()); |
|||
uniform_int_distribution<> dist_bucket(0, bucket_count - 1); |
|||
while (true) { |
|||
int from = dist_bucket(gen); |
|||
int to = dist_bucket(gen); |
|||
if (from != to) { |
|||
lock_guard<mutex> lock_first(bucket_mutex[min(from, to)]); |
|||
lock_guard<mutex> lock_second(bucket_mutex[max(from, to)]); |
|||
uniform_int_distribution<> dist_amount(0, buckets[from]); |
|||
int amount = dist_amount(gen); |
|||
buckets[from] -= amount; |
|||
buckets[to] += amount; |
|||
} |
|||
} |
|||
} |
|||
void print_buckets(const array<int, bucket_count>& buckets) { |
|||
int total = 0; |
|||
for (const int& bucket : buckets) { |
|||
total += bucket; |
|||
cout << setw(3) << bucket << ' '; |
|||
} |
|||
cout << "= " << setw(3) << total << endl; |
|||
} |
|||
int main() { |
|||
random_device rd; |
|||
mt19937 gen(rd()); |
|||
uniform_int_distribution<> dist(0, 99); |
|||
array<int, bucket_count> buckets; |
|||
array<mutex, bucket_count> bucket_mutex; |
|||
for (int& bucket : buckets) { |
|||
bucket = dist(gen); |
|||
} |
|||
print_buckets(buckets); |
|||
thread t_eq(equalizer, ref(buckets), ref(bucket_mutex)); |
|||
thread t_rd(randomizer, ref(buckets), ref(bucket_mutex)); |
|||
while (true) { |
|||
this_thread::sleep_for(chrono::seconds(1)); |
|||
for (mutex& mutex : bucket_mutex) { |
|||
mutex.lock(); |
|||
} |
|||
print_buckets(buckets); |
|||
for (mutex& mutex : bucket_mutex) { |
|||
mutex.unlock(); |
|||
} |
|||
} |
|||
return 0; |
|||
}</lang> |
|||
=={{header|C sharp}}== |
=={{header|C sharp}}== |