Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
125
Task/Atomic-updates/C-sharp/atomic-updates.cs
Normal file
125
Task/Atomic-updates/C-sharp/atomic-updates.cs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
using System; //Rand class
|
||||
using System.Threading; //Thread, Mutex classes
|
||||
public class ThreadSafeBuckets
|
||||
{
|
||||
//This class is thread safe, and ensures that all operations on it are atomic.
|
||||
//Calling threads do not need to ensure safety.
|
||||
Random rand = new Random();
|
||||
int[] Buckets;
|
||||
object[] locks; //Mutexes for each bucket so they can lock individually
|
||||
public int BucketCount { get; private set; }
|
||||
public ThreadSafeBuckets(int bucketcount)
|
||||
{
|
||||
//Create buckets+mutexes and fill them with a random amount
|
||||
BucketCount = bucketcount;
|
||||
Buckets = new int[bucketcount];
|
||||
locks = new object[bucketcount];
|
||||
int startingtotal = 0;
|
||||
for (int i = 0; i < BucketCount; i++)
|
||||
{
|
||||
locks[i] = new object();
|
||||
Buckets[i] = rand.Next(30);
|
||||
startingtotal += Buckets[i];
|
||||
}
|
||||
//Print the starting total
|
||||
Console.WriteLine("Starting total: " + startingtotal);
|
||||
}
|
||||
public int GetBucketValue(int i)
|
||||
{
|
||||
return Buckets[i];
|
||||
}
|
||||
public void Transfer(int i, int j, int amount)
|
||||
{
|
||||
//Transfer amount from bucket i to bucket j
|
||||
if (i > BucketCount || j > BucketCount || i < 0 || j < 0 ||
|
||||
i == j || amount < 0)
|
||||
return;
|
||||
|
||||
//To prevent deadlock, always lock the lower bucket first
|
||||
lock (locks[Math.Min(i, j)])
|
||||
lock (locks[Math.Max(i, j)])
|
||||
{
|
||||
//Make sure don't transfer out more than is in the bucket
|
||||
amount = Math.Min(amount, Buckets[i]);
|
||||
|
||||
//Do the transfer
|
||||
Buckets[i] -= amount;
|
||||
Buckets[j] += amount;
|
||||
}
|
||||
}
|
||||
|
||||
public void PrintBuckets()
|
||||
{
|
||||
int counter = 0;
|
||||
//Lock all the buckets in sequential order and print their contents
|
||||
for (int i = 0; i < BucketCount; i++)
|
||||
{
|
||||
Monitor.Enter(locks[i]);
|
||||
Console.Write(Buckets[i] + " ");
|
||||
counter += Buckets[i];
|
||||
}
|
||||
//Print the bucket total, then unlock all the mutexes
|
||||
Console.Write("= " + counter);
|
||||
Console.WriteLine();
|
||||
|
||||
foreach (var l in locks)
|
||||
Monitor.Exit(l);
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
static ThreadSafeBuckets TSBs;
|
||||
|
||||
public static void Main(){
|
||||
//Create the thread-safe bucket list
|
||||
TSBs = new ThreadSafeBuckets(10);
|
||||
TSBs.PrintBuckets();
|
||||
//Create and start the Equalizing Thread
|
||||
new Thread(new ThreadStart(EqualizerThread)).Start();
|
||||
Thread.Sleep(1);
|
||||
//Create and start the Randamizing Thread
|
||||
new Thread(new ThreadStart(RandomizerThread)).Start();
|
||||
//Use this thread to do the printing
|
||||
PrinterThread();
|
||||
}
|
||||
//EqualizerThread runs on it's own thread and randomly averages two buckets
|
||||
static void EqualizerThread()
|
||||
{
|
||||
Random rand = new Random();
|
||||
while (true)
|
||||
{
|
||||
//Pick two buckets
|
||||
int b1 = rand.Next(TSBs.BucketCount);
|
||||
int b2 = rand.Next(TSBs.BucketCount);
|
||||
//Get the difference
|
||||
int diff = TSBs.GetBucketValue(b1) - TSBs.GetBucketValue(b2);
|
||||
//Transfer to equalize
|
||||
if (diff < 0)
|
||||
TSBs.Transfer(b2, b1, -diff / 2);
|
||||
else
|
||||
TSBs.Transfer(b1, b2, diff/2);
|
||||
}
|
||||
}
|
||||
//RandomizerThread redistributes the values between two buckets
|
||||
static void RandomizerThread()
|
||||
{
|
||||
Random rand = new Random();
|
||||
while (true)
|
||||
{
|
||||
int b1 = rand.Next(TSBs.BucketCount);
|
||||
int b2 = rand.Next(TSBs.BucketCount);
|
||||
int diff = rand.Next(TSBs.GetBucketValue(b1));
|
||||
TSBs.Transfer(b1, b2, diff);
|
||||
}
|
||||
}
|
||||
//PrinterThread prints the current bucket contents
|
||||
static void PrinterThread()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Thread.Sleep(50); //Only print every few milliseconds to let the other threads work
|
||||
TSBs.PrintBuckets();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue