Click here to Skip to main content
15,902,198 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Need to know if this idea makes sense and is doable: I'm using multi-threaded producer consumer queue design pattern. The building of the queue is too fast and not allowing my thread enough time to process the data in a timely fashion so I'm trying to create threads dynamically if the queue reaches a certain size. Checkout this code I'm trying to implement and let me if it's logical and doable:
const int MAX_QUEUE = 1000;

Queue<string> que = new Queue<string>();
EventWaitHandle ewh =  new AutoResetEvent(false);
object sync = new object();
MyWorker  myWorker = new MyWorker(sync,ewh,que);
Thread thrd = new Thread(myWorker.Work);
thrd.Start();


private void producer(string task)
{
  lock(sync)
  {
    que.Enqueue(task);
    
    // I'm trying to create multiple threads dynamically to assist int processing the queue vs only
    // using the one thread that I instantiated...
    if(que.Count > MAX_QUEUE)
    { 
      new Thread(delegate(){ new MyWorker(que,sync,ewh).Work();}).Start();
    }
  }
  ewh.Set();
}

class MyWorker
{
  object sync;
  EventWaitHandle ewh;
  Queue<string> que;

  public MyWorker(object sync, EventWaitHandle ewh, Queue<string> que)
  {
     this.sync = sync;
     this.ewh = ewh;
     this.que = que;
   }

   public void Work()
   {
      while(true)
      {
         string task = "";
         lock(sync)
         {
           if(que.Count > 0)
           {
             task = que.Dequeue();
           }
         }
         
           if(task != "")
           {
             // process task...
           }
           else
             ewh.WaitOne();
       }
   }
}</string></string></string></string></pre>
[edit]Code Block added - OriginalGriff[/edit]
[edit2]Spurious string tags removed - OriginalGriff[/edit2]</string></string></string></string>
Posted
Updated 26-Mar-11 6:13am
v12

I see a few problems. First I can't see how the threads can ever end, they'll be stuck in that while(true) loop forever. There maybe some code missing but you need to make sure you can break out of that loop to allow the thread to exit properly.

Secondly, if you add more threads than there are cores on a processor then you won't gain any performance increase because while some threads will be running others will be waiting for their time on the processor. It could actually slow you down.

So what you may want to do is create a fixed number of threads as soon as you start (you should be able to use Environment.ProcessorCount to get the number of threads that can run in parallel) and then if your queue starts to get full you will simply have to stop adding items to it until there is enough room.

EDIT: Forgot to mention, you may also want to look into using a Thread Pool if your going to be creating lots of threads on the fly http://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx[^]
 
Share this answer
 
v2
Comments
d.allen101 26-Mar-11 12:25pm    
thanks for the reply SK Genius...as far as ending the threads in the while loop I can implement IDisposable and kill the threads I didn't include it in my example...but anyway, I'm not quite sure I understand what your explaining to me as far is creating more threads than I have cores???? if my machine is a quadCore machine are you saying that I can only use 4 threads at a time? also how do I know how many threads I need in advance to process my queue?
Anthony Mushrow 26-Mar-11 12:33pm    
You can make as many threads as you like, but if you have a quad core cpu then yes, only 4 of your threads will ever be running at exactly the same time.

Environment.ProcessorCount should tell you the number of logical processors / cores that are on the current machine, you can use that to determine how many threads you should create
d.allen101 26-Mar-11 12:36pm    
i'm familiar with enviorment.processorcount...that's weird because in my production code if I use only 4 threads to process the queue it consumes too much memory and eventually crashes but if I use approximately 10-12 threads the application can handle the build up of the queue and process the data just fine...and by the way my machine isn't running 10-12 processors it's a quadCore machine.
d.allen101 26-Mar-11 12:44pm    
but logically that makes PERFECT sense what you're saying SK Genius but I'm not quite sure if it's correct because I'm almost 100% certain that more than 4 threads can be ran simultaneously! otherwise how would it be possible for the OS to run, windows media player, web browser, etc and all of the various things that are happing in the background in these apps?
Anthony Mushrow 26-Mar-11 12:53pm    
What actually happens is that each thread is given some time on the processor before it is switched out with another process so the threads aren't actually running in parallel, they are just interleaved with each other. Also switching threads a lot can hamper performance (assuming all of the threads are actually busy, rather than waiting for events or data). Think of a computer that locks up because a single greedy process is using all of the available cpu time, with other threads getting very little time to do anything.

I can't explain why 10 busy threads would be able to handle more data, unless the work that they do involves waiting on other hardware (reading from disk, network communications etc.) in which case the optimum number of threads to use is going to be a little more difficult to find. For certain though you don't want to just keep creating threads forever, you might be better off working something out with a ThreadPool, which will manage the threads for you.
MSIL
MyWorker worker = new MyWorker();

private void producer(string Task)
{
    Thread taskthread = new Thread(new ParameterizedThreadStart(worker.Work));
    taskthread.Start(Task);
}

class MyWorker
{
    public MyWorker()
    {
    }

    public void Work(object objTask)
    {
        string Task = (string)objTask;

        if (Task != "")
        {
            // process task...
        }
    }
}


In this way you will let windows do the cue-ing for you, and you still can use the commen variables of the MyWorker class in your thread.
 
Share this answer
 
v2
Comments
d.allen101 26-Mar-11 14:56pm    
because that wouldn't be practical. I'm receiving items from a real-time stock market data-feed at a rate of approximately 10-15 messages per second
willempipi 27-Mar-11 0:51am    
Tonight, I started coding on this problem, but this left me with some arcitecture questions I just don't have the time to ask and solve right now, and future more, it's your project right;). You'll have to go for the 3th solution and ask yourself how much time it takes to do one task. Maybe my solution will be a good solution because many people underestimate the power of multitasking with threads, renember, we're not in the 90's with single core computers that can do 200 mhz, we now have 4 cores that do more then a 100 times more calculations a second, each.

If your "process task" takes little processor time(test with taskmanager), you should try/compair it to my method. If it takes a lot of processor time, you might be better off with your approice with a queue system or maybe some variation of it. Like limiting the number of threads you start by adding a timer like thread that starts the threads that handle the process task list added by the producer.
This problem is solved in my Tips/Tricks article: Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900