CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Mar 2011
    Posts
    2

    Threads not entirely Concurrent...

    Hello all,

    I have been trying to create a simple program that demonstrates concurrency in programming using c# Threads, but I am getting some strange behaviour that I hope you can help with!


    Basically I create 4 Threads, all with identical functions that write results out to seperate variables, then display them in Test Boxes.

    The problem comes when I wish to Synchronise the completion of the threads so that the results come through together with a timer attached.

    Executed without the joins, the program executes as you would expect, but the end data is incorrect as the processes have no completed at the time the main Thread processes the data...
    Watching the Resource monitor of the PC, it takes approx 18 seconds at 90+% CPU time across all 4 CPU's to complete, before dropping back to an idle CPU.

    Executed WITH the joins, the program runs at 90+% CPU time for about 10 seconds, then drops to 25% for around 40 seconds before populating each textBox in turn, with a 5-6 second delay between them, suggesting that the code STARTS running concurrently, but then falls back to a single process for the rest of the time...

    This is very frustrating, and I would appreciate and insights into why this could be happening!

    Thanks


    public partial class Form1 : Form
    {

    Stopwatch timer = new Stopwatch();

    BigInteger bi1 = new BigInteger(1); // 1 Variable per Thread
    BigInteger bi2 = new BigInteger(1);
    BigInteger bi3 = new BigInteger(1);
    BigInteger bi4 = new BigInteger(1);
    BigInteger biFinal = new BigInteger(1); // Final result. Processed in Main thread at end

    int operations1 = 0;
    int operations2 = 0;
    int operations3 = 0;
    int operations4 = 0;

    int finalOperations = 0;
    double opsPerSecs;

    int factorial = 100000;

    public void threadFunction1()
    {
    for (int i = 1; i <= factorial; i++)
    {
    bi1 *= i;
    operations1++;
    }
    }

    public void threadFunction2()
    {
    for (int i = 1; i <= factorial; i++)
    {
    bi2 *= i;
    operations2++;
    }
    }

    public void threadFunction3()
    {
    for (int i = 1; i <= factorial; i++)
    {
    bi3 *= i;
    operations3++;
    }
    }

    public void threadFunction4()
    {
    for (int i = 1; i <= factorial; i++)
    {
    bi4 *= i;
    operations4++;
    }
    }

    public Form1()
    {
    InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {

    List<Thread> threads = new List<Thread>(); //Thread Array

    Thread child = new Thread(threadFunction1);
    threads.Add(child);
    child.Start();

    Thread child2 = new Thread(threadFunction2);
    threads.Add(child2);
    child2.Start();

    Thread child3 = new Thread(threadFunction3);
    threads.Add(child3);
    child3.Start();

    Thread child4 = new Thread(threadFunction4);
    threads.Add(child4);
    child4.Start();

    timer.Start();
    richTextBox1.Text = "Thread 1 Started";
    richTextBox2.Text = "Thread 2 Started";
    richTextBox3.Text = "Thread 3 Started";
    richTextBox4.Text = "Thread 4 Started";

    foreach (Thread t in threads)
    {
    t.Join();
    }

    timer.Stop();

    richTextBox1.Text = bi1.ToString();
    richTextBox2.Text = bi2.ToString();
    richTextBox3.Text = bi3.ToString();
    richTextBox4.Text = bi4.ToString();

    finalOperations = operations1 + operations2 + operations3 + operations4;
    biFinal = bi1 + bi2 + bi3 + bi4;

    double timerRound = Math.Round(timer.Elapsed.TotalSeconds, 2);
    opsPerSecs = Math.Round(finalOperations/ timerRound, 2);


    richTextBox5.Text = "Your PC Performed " + finalOperations.ToString() + " operations in "+ timer.Elapsed.TotalSeconds +" Seconds \nThis calculates to "+opsPerSecs+" Operations per second\n\nFinal result:\n" + biFinal;


    }

    }

  2. #2
    Join Date
    Jul 2007
    Location
    Illinois
    Posts
    517

    Re: Threads not entirely Concurrent...

    Wow, you're going to end up with some pretty massive integers. Really, it looks like your threads are completing concurrently because of the calls to Join(), but you may be having problems in calculating those very large numbers. I mean, when you Join() with the threads using the foreach loop, it will block the calling thread until the Join() thread has terminated. So I don't think it's an issue there... After the 64th factorial you surpass what can be stored in a 64-bit unsigned integer (i.e. a UInt64 or ulong.) Which intern means that in order to store a value calculated from a factorial of 100000, you would need a 100000 bit unsigned integer! (someone check my math :P) That's 12+ KB of memory just to store one integer value.
    Last edited by RaleTheBlade; March 10th, 2011 at 12:55 PM.
    R.I.P. 3.5" Floppy Drives
    "I know not with what weapons World War III will be fought, but World War IV will be fought with sticks and stones." - Albert Einstein

  3. #3
    Join Date
    Mar 2011
    Posts
    2

    Re: Threads not entirely Concurrent...

    I changed the algorithm to calculate Pi, and the CPU's sit at 100&#37; for the duration =)

    I am now using:

    double pi = Enumerable.Range(0, 100000000).Aggregate(0d, (tot, next) => tot += Math.Pow(-1d, next) / (2 * next + 1) * 4);

    but this is cut/paste from someones blog... Could someone explain how this works?
    The result is quite short for the calculation time!

    Does a double automatically truncate to a set number of DP's?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured