Reputation:
I'm doing one program which needs multithreading synchronization. Here are my methods:
private void RunSimulation()
{
int sideSize = (int)Math.Ceiling((double)_simulationField.GetLength(0) / (double)MAX_SECTOR_SIZE);
int threadsCount = sideSize * sideSize;
sync = new bool[threadsCount + 1];
for (int i = 0; i < sync.Length; i++)
{
sync[i] = false;
}
for (int sector = 0; sector <= threadsCount; sector++)
{
Thread sectorThread = new Thread(DoSector);
sectorThread.IsBackground = true;
sectorThread.Start(sector);
}
}
And:
private void DoSector(object obj)
{
int sector = (int)obj;
Library.Pair sectorPosition = GetSectorPosition(sector);
while (true)
{
for (int i = sectorPosition.X; i < sectorPosition.X + MAX_SECTOR_SIZE && i < _simulationField.GetLength(0); i++)
{
for (int j = sectorPosition.Y; j < sectorPosition.Y + MAX_SECTOR_SIZE && j < _simulationField.GetLength(1); j++)
{
if (_simulationField[i, j] != null)
{
MoveCreature(_simulationField[i, j], i, j);
}
}
}
sync[sector] = true;
while (sync.Contains(false) && sector != sync.Length)
{
Thread.Sleep(10);
}
if (sector == sync.Length)
{
for (int i = 0; i < sync.Length; i++)
{
sync[i] = true;
}
}
Thread.Sleep(500);
}
}
So you can see that I'm using an array for the synchronization. But I'm wandering is it good way to do this? Here the operation sync.Contains is with complexity O(n) and it's in loop...Is there a better way to do the synchronization?
Upvotes: 0
Views: 362
Reputation: 1035
Using an array to sync is not thread safe, yet alone "sync.Contains(false)".
What if two threads are running sync.Contains(false) at the same time and both come back false?
Also, I see your ThreadCount is sideSize squared. It is very inefficient to create lots of threads. the more threads you have, the more context switches you have. A context switch is about 8000 clock cycles. Also, creating a thread costs about 100,000 clock cycles and each thread must have its own stack which is about 4MB by default.
What you want is about as many threads as cores and each thread to pull from a queue and process its work.
You're probably best off using the thread pool, but I also see your threads are in a while(true), which means they never end. The thread pool isn't meant for long running threads.
Over all, I think your design needs some work. Since you seem to be learning, I would recommend a design that allows the use of the thread pool, instead of while(true) loops.
Someone else might be able to give you a "name" for a known design pattern that would work for you, but I'm not up on names for designs patterns.
Upvotes: 0