none
strange threads behavior problem RRS feed

  • Question

  • hi all.

    I have a code segment that create 6 threads at each run.

    what i've noticed is when i open the task manager. after say about an hour of program running my thread count is betwin 60-90 threads.

    what i dont understand is: if my threads are declared localy then why the thread count is incresing

    (notice that the internal loop does not allowed operation until the previos ended)

    i've posted a code segment similier to my code.

    10X

      

        private void MainLoop()
        {
          while (Run)
          {
            while (threadFlag)
            {
              while ((ThreadControl.First | ThreadControl.Sec |     
              ThreadControl.Third) != _flag) Thread.Sleep(1);
              _flag = ThreadControl.None;
              RunMainThread();
    
            }
          }
        }
    
        private void RunMainThread()
        {
          Thread t = new Thread(new ThreadStart(DOWork1));
          t.Start();
          Thread t1 = new Thread(new ThreadStart(Dowork2));
          t1.Start();
          Thread t2 = new Thread(new ThreadStart(DoWork3));
          t2.Start();
        }
    
        private void DOWork1()
        {
          Thread.Sleep(2000);
          _flag = _flag | ThreadControl.First;
          
    
        }
    
        private void Dowork2()
        {
          Thread.Sleep(3000);
          _flag = _flag | ThreadControl.Sec;
          
        }
    
        private void DoWork3()
        {
          Thread.Sleep(1000);
          _flag = _flag | ThreadControl.Third;
          
        }
    
    
     [Flags]
      enum ThreadControl
      {
        None=0,
        First=1,
        Sec=2,
        Third=4
      }

    
    

    Tuesday, April 27, 2010 11:45 AM

Answers

  • What I am saying is:

    Your flag starts with, say, 0000

    Thread 1 reads the value (0000), alters it to 0001 and writes the value, all OK.

    Now imagine Thread 2 and 3 acting as following:

    Thread 3 reads the value (0001), while it is changing it to 0101, here comes thread 2 and reads the still unchanged value (0001), changes it to 0011), meanwhile thread 3 finishes and stores 0101, finally thread 2 overwrites with its own new value, so _flag ends up showing 0011 and not the expected 0111...

    This is called a race condition: your thread code expects every other thread to have finished (or not have started) to modify _flag.

    Cristian.

    • Marked as answer by SamAgain Friday, May 7, 2010 8:37 AM
    Tuesday, April 27, 2010 7:19 PM
  • Well another suggestion. If possible I would try to use the threadpool thread and let CLR manage the threads. Given your scenario I would use the threadpool threads(Threadpool.QueueUserWorkItem)
    • Marked as answer by SamAgain Friday, May 7, 2010 8:37 AM
    Tuesday, April 27, 2010 9:27 PM
  • The above code will not create  all those thread you´re seeing, running it here (mildly altered to work as a console app, show, as expected, no more than 4 or 5 threads running max, even after more than an hour, as expected.

    Maybe the problem is somewhere else in your code?

    Cristian.

    • Marked as answer by SamAgain Friday, May 7, 2010 8:37 AM
    Wednesday, April 28, 2010 1:05 AM

All replies

  • You example is incomplete... Also this statement is confusing: if my threads are declared localy then why the thread count is incresing

    Each time RunMainThread() is called 3 new threads are created.

    Tuesday, April 27, 2010 12:19 PM
  • "Each time RunMainThread() is called 3 new threads are created."

    thats right 3 threads are created but  when each thread finishes his callback  the thread should be disposed.

     

    "Also this statement is confusing: if my threads are declared localy then why the thread count is incresing"

     

    what i ment is: what i'm expecting to see in the task manager is thread count up by 3 threads and  then thread count reduce by 3 threads and over and over again

    Tuesday, April 27, 2010 12:27 PM
  • Independently of the thread count raising, your threads are all over your _flag variable: it is not guaranteed to contain an accurate representation of your state (because _flag = _flag | ThreadControl... is not atomic, each thread reads the _flag, ors it (in the meanwhile another thread reads the unchanged flag), writes it back (the other thread ors the original value, writes it back, overwriting the previous value...) and so on).

    Cristian.

    Tuesday, April 27, 2010 1:37 PM
  • i don't quite understand your answer..

    suppose  t change the flag:

    _flag= 00000000 | first= 00000001

    results in 00000001

    if t1 will access the _flag when i'ts set to None or set to sec ther results(for the first bit) will be the same cause:

    _flag=00000000 | sec=00000010

    results in

    00000010

    or if 

    _flag=00000001| sec=00000010

    result will be 00000011

    as you can see the first bit is not inflluenced by the or operation

     

     

    Tuesday, April 27, 2010 2:28 PM
  • What I am saying is:

    Your flag starts with, say, 0000

    Thread 1 reads the value (0000), alters it to 0001 and writes the value, all OK.

    Now imagine Thread 2 and 3 acting as following:

    Thread 3 reads the value (0001), while it is changing it to 0101, here comes thread 2 and reads the still unchanged value (0001), changes it to 0011), meanwhile thread 3 finishes and stores 0101, finally thread 2 overwrites with its own new value, so _flag ends up showing 0011 and not the expected 0111...

    This is called a race condition: your thread code expects every other thread to have finished (or not have started) to modify _flag.

    Cristian.

    • Marked as answer by SamAgain Friday, May 7, 2010 8:37 AM
    Tuesday, April 27, 2010 7:19 PM
  • 10x Cristian.

    i'll make sure to protect the flag operation

    but still any idea about the thread count?

    Tuesday, April 27, 2010 8:31 PM
  • Well another suggestion. If possible I would try to use the threadpool thread and let CLR manage the threads. Given your scenario I would use the threadpool threads(Threadpool.QueueUserWorkItem)
    • Marked as answer by SamAgain Friday, May 7, 2010 8:37 AM
    Tuesday, April 27, 2010 9:27 PM
  • The above code will not create  all those thread you´re seeing, running it here (mildly altered to work as a console app, show, as expected, no more than 4 or 5 threads running max, even after more than an hour, as expected.

    Maybe the problem is somewhere else in your code?

    Cristian.

    • Marked as answer by SamAgain Friday, May 7, 2010 8:37 AM
    Wednesday, April 28, 2010 1:05 AM
  • Hi Elad_me,

    Is there anything wrong with this line?

     while ((ThreadControl.First|ThreadControl.Sec |ThreadControl.Third) != _flag) 

    Since, the code above is different with:

    while ((ThreadControl.First != _flag) | (ThreadControl.Sec != _flag) |(ThreadControl.Third != _flag)) 


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, May 4, 2010 5:54 AM
  • Hi Elad Me,

        Just some additional information:

        1. Safe Thread Synchronization

        2. Thread safety


    Please mark the right answer at right time.
    Thanks,
    Sam
    Friday, May 7, 2010 8:40 AM