Skip to content

Instantly share code, notes, and snippets.

@rogeralsing
Created March 17, 2015 07:02
Show Gist options
  • Save rogeralsing/98f9c701a092fcd2925b to your computer and use it in GitHub Desktop.
Save rogeralsing/98f9c701a092fcd2925b to your computer and use it in GitHub Desktop.
Naive threadpool
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace NaiveThreadPool
{
class Program
{
static void Main()
{
int count = 0;
var myThreadpool = new MyThreadPool(10);
const int totalWork = 10000000;
var workDone = new ManualResetEventSlim(false);
Console.WriteLine("Press any key to start..");
Console.ReadKey();
var sw = Stopwatch.StartNew();
for (int i = 0; i < totalWork; i++)
{
myThreadpool.AddWork(() =>
{
if (Interlocked.Increment(ref count) == totalWork)
{
workDone.Set();
}
});
}
workDone.Wait();
Console.WriteLine(sw.Elapsed);
Console.ReadLine();
}
}
public class MyThreadPool
{
private volatile int _index;
private readonly List<Worker> _workers = new List<Worker>();
public MyThreadPool(int nrOfWorkers)
{
for (int i = 0; i < nrOfWorkers; i++)
{
var worker = new Worker();
_workers.Add(worker);
}
}
public void AddWork(Action work)
{
//using volatile instead of interlocked, no need to be exact, gaining 20% perf
_workers[_index ++ % _workers.Count].AddWork(work);
}
}
public class Worker
{
private readonly ConcurrentQueue<Action> _work = new ConcurrentQueue<Action>();
private readonly ManualResetEventSlim _event = new ManualResetEventSlim(false);
public Worker()
{
var thread = new Thread(() =>
{
while (true)
{
//suspend if no more work is present
_event.Wait();
Action action;
while (_work.TryDequeue(out action))
{
action();
}
if (_work.Count == 0)
{
_event.Reset();
}
if (_work.Count > 0)
{
_event.Set();
}
}
})
{
IsBackground = true
};
thread.Start();
}
public void AddWork(Action work)
{
_work.Enqueue(work);
_event.Set();
}
}
}
@rogeralsing
Copy link
Author

This one does about 8 000 000 actions per second on my machine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment