Reputation: 81
I am creating an component which performs sequential processing on inputs. As it will be hosted in several different processes, I need it to be thread safe. At first, I intentionally left out thread safety from the code. Now it is time to introduce that.
First, I wanted to provoke an error to start with, but was not able to. Here is a simplified version of the code for the processing engine:
public Document DoOrchestration(Document input)
{
Document output = new Document();
foreach (var orchestrationStep in m_OrchestrationSteps)
{
var processor = GetProcessor(orchestrationStep).Clone();
output = processor.Process(input);
input = output;
}
return output;
}
The processors can be developed by other people in my organisation, and that can include some complex initialization. They may also be thread unsafe, so I use the Prototype Pattern to get unique instances of the to avoid threading issues in those.
To test this function I used the following code:
for (int i = 0; i < 20000; i++)
{
Thread t = new Thread(() => TestOrchestration(i));
t.Start();
}
void TestOrchestration(int number)
{
Document doc = new Document(string.Format("Test {0}", number));
doc = DoOrchestration(doc);
if (doc.ToString().Substring(0,35) != strExpectedResult)
{
System.Console.WriteLine("Error: {0}", doc.ToString();
}
}
I expected that some of the threads would collide with another and mix up their results, but to my surprise that did not happen.
There is probably a easy and logical explanation to this, but it eludes me. Or is it just that the code is too simple to result in two threads fiddling with the input/output variables at the same time?
Upvotes: 4
Views: 131
Reputation: 10773
I think your test function is almost complete before next thread starts. You can make all the threads wait on an ManualResetEventSlim before invoking the orchestration function and then set the ManualResetEventSlim
That way all your threads will infact try to invoke orchestration at the same time.
Also possibly you would not need 20,000 threads to simulate this behavior if all threads male orchestracion call at almost the same time
ManualResetEventSlim manualEvent = new ManualResetEventSlim (false);
for (int i = 0; i < 20000; i++)
{
Thread t = new Thread(() => TestOrchestration(i));
t.Start();
}
manualEvent.Set();
void TestOrchestration(int number)
{
manualEvent.Wait();
Document doc = new Document(string.Format("Test {0}", number));
doc = DoOrchestration(doc);
if (doc.ToString().Substring(0,35) != strExpectedResult)
{
System.Console.WriteLine("Error: {0}", doc.ToString();
}
}
Upvotes: 0
Reputation: 9780
You could use the ManualResetEvent
for simultaneous continuation of any number of awaiting threads.
Upvotes: 0
Reputation: 365
I would assume that due to the simplicity of your test function, your threads do not even get the time to spawn in a large quantity before the previous one is done with it's work. Consider using a barrier to allow all threads to spawn before you start the computational step. Also, you will want to consider increasing the complexity of your test case, for instance by performing several of the same operation in the same loop (starting a thread is expensive, and allows other cores to complete their work before you even get around to the resource contention.
Generally, resource contention can be provoked by having rapid access to the same resource over a longer period of time, your test case does not seem to allow for this. As an aside, I would strongly recommend that you design for thread safety in mind, instead of introducing this later. When working with the code you have a better understanding of resource access patterns than you will have when analyzing the code at a later stage.
Upvotes: 0
Reputation: 5649
Check out CHESS.
CHESS is a tool for finding and reproducing Heisenbugs in concurrent programs. CHESS repeatedly runs a concurrent test ensuring that every run takes a different interleaving. If an interleaving results in an error, CHESS can reproduce the interleaving for improved debugging. CHESS is available for both managed and native programs.
Upvotes: 1