Start multiple threads at the same time without slowing down - c#

I know that this question is everywhere but I couldn't find what suits me.
I am trying to start 10 threads running at the same time without slowing down each thread.
My problem is that when I start the threads manually, they are very fast. But if I start them using a loop, they are very slow.
Here is where it is fast:
Thread tid1 = new Thread(new ThreadStart(Thread));
tid1.Start();
Thread tid2 = new Thread(new ThreadStart(Thread));
tid2.Start();
Thread tid3 = new Thread(new ThreadStart(Thread));
tid3.Start();
Thread tid4 = new Thread(new ThreadStart(Thread));
tid4.Start();
Thread tid5 = new Thread(new ThreadStart(Thread));
tid5.Start();
Thread tid6 = new Thread(new ThreadStart(Thread));
tid6.Start();
Thread tid7 = new Thread(new ThreadStart(Thread));
tid7.Start();
Thread tid8 = new Thread(new ThreadStart(Thread));
tid8.Start();
Thread tid9 = new Thread(new ThreadStart(Thread));
tid9.Start();
Thread tid10 = new Thread(new ThreadStart(Thread));
tid10.Start();
Slow methods which I've tried:
1:
foreach (var i in Enumerable.Range(1, 10))
{
Thread tid = new Thread(new ThreadStart(Thread));
tid.Start();
}
2:
Parallel.ForEach(Enumerable.Range(1, 10), i =>
{
Thread tid = new Thread(new ThreadStart(Thread));
tid.Start();
});
Any help would be appreciated.
Thanks!

After a bit of tinkering, this method seems quite quick:
List<Thread> threadlist = new List<Thread>();
for (int i = 0; i <= 10; i++)
threadlist.Add(new Thread(new ThreadStart(wastetime)));
foreach (Thread t in threadlist)
t.Start();
Make a list of the threads, then start them once the list is assembled. Bonus points if the thread creation sub is on it's own mini thread to.
Though beware of magic, each thread has overhead and extra processing involved, so if the tasks being performed on each thread are short-lived, the whole threading idea will be losing performance rather than gaining it.

Related

mimic concurrent threads (on the same resource/method)

Is there any way that I mimic in an short simple illustrative example of concurrent threads, that 2 threads can start the same method at the same time, and the processing is mixed between the two?
In the below example, I want to see sth like:
1 thread1
1 thread2
2 thread1
2 thread2
..
10 thread1
10 thread2
Instead, I get something like:
1 thread1
2 thread1
...
10 thread1
1 thread2
2 thread2
...
10 thread2
Be kind, I'm just starting to learn threads.
In short, I want to simulate the effect of the two threads starting at exactly the same time, not one immediately after the other.
After I achieve the above mentioned, I want to use the lock in order for thread1 to completely finish executing before starting thread2. This already happens in my example even before employing lock.
using System;
using System.Threading;
public class Program
{
public class C1
{
private object obj = new object();
public void Ten()
{
//lock(obj)
//{
for(int i=1; i<=10; i++)
{
Console.WriteLine(i + " " + Thread.CurrentThread.Name);
}
//}
}
}
public static void Main()
{
Thread t1 = new Thread(new ThreadStart(new C1().Ten));
Thread t2 = new Thread(new ThreadStart(new C1().Ten));
t1.Name = "thread1";
t2.Name = "thread2";
t1.Start();
t2.Start();
}
}
as ESG mentioned in the comment, the code runs too fast. That's why you are not getting expected output. Try adding some sleep inside the loop to get the expected result.
using System;
using System.Threading;
public class Program
{
public class C1
{
private static object obj = new object();
public void Ten()
{
//lock(obj)
//{
for(int i=1; i<=10; i++)
{
Console.WriteLine(i + " " + Thread.CurrentThread.Name);
Thread.Sleep(1000); //<-- add sleep
}
//}
}
}
public static void Main()
{
Thread t1 = new Thread(new ThreadStart(new C1().Ten));
Thread t2 = new Thread(new ThreadStart(new C1().Ten));
t1.Name = "thread1";
t2.Name = "thread2";
t1.Start();
t2.Start();
}
}
On the second note about locking the resource so that thread2 should wait for thread1 to complete. You will need to mark the obj as static variable.
Hope it helps.

Is it possible to know which thread completed first?

If I have fire 3 threads. Is it possible to know which thread completed first.
Some sample code
Thread thread1 = new Thread(() => MyFunc());
Thread thread2 = new Thread(() => MyFunc());
Thread thread3 = new Thread(() => MyFunc());
thread1.Start();
thread2.Start();
thread3.Start();
while (thread1.IsAlive || thread2.IsAlive || thread3.IsAlive)
{
//I need condition to which thread dead first.
}
You can use Interlocked.CompareExchange to set the winning thread:
static Thread winner = null;
private static void MyFunc()
{
Thread.Sleep((int)(new Random().NextDouble() * 1000));
Interlocked.CompareExchange(ref winner, Thread.CurrentThread, null);
}
public static void Main()
{
Thread thread1 = new Thread(() => MyFunc());
Thread thread2 = new Thread(() => MyFunc());
Thread thread3 = new Thread(() => MyFunc());
thread1.Name = "thread1";
thread2.Name = "thread2";
thread3.Name = "thread3";
thread1.Start();
thread2.Start();
thread3.Start();
thread1.Join();
thread2.Join();
thread3.Join();
Console.WriteLine("The winner is {0}", winner.Name);
}
Live Demo
UPDATE: If you don't want all threads to finish before you check, there is an easier method using AutoResetEvents and WaitHandle.WaitAny():
private static void MyFunc(AutoResetEvent ev)
{
Thread.Sleep((int)(new Random().NextDouble() * 1000));
ev.Set();
}
public static void Main()
{
AutoResetEvent[] evs = {new AutoResetEvent(false), new AutoResetEvent(false), new AutoResetEvent(false)};
Thread thread1 = new Thread(() => MyFunc(evs[0]));
Thread thread2 = new Thread(() => MyFunc(evs[1]));
Thread thread3 = new Thread(() => MyFunc(evs[2]));
thread1.Start();
thread2.Start();
thread3.Start();
int winner = WaitHandle.WaitAny(evs);
Console.WriteLine("The winner is thread{0}", winner + 1);
}
Live Demo
one simple workaround would be that you write the thread name to a list or something when it completes?
All threads can have an arbitrary delay after the last instruction of your code is completed. After the last instruction has run the OS still has some work to do. It can take an arbitrarily long time.
For that reason it is never meaningful to find out what thread completed first. This is the XY-Problem. This question is meaningless. Its answer will not help you accomplish anything. Ask a new question with the real problem.
You probably want to tell which one of multiple side-effects happened first. Even if they completed in order A, B the threads they ran on can complete in any order. The thread order tells you nothing.

How do i ensure statement gets executed after all the threads have completed execution

say my main thread calls a loop which makes new threads and starts them on some other function.
for (int i = 0; i < numberOfThreads; i++)
{
Thread thread = new Thread(start);
thread.Start();
}
call_This_Function_After_All_Threads_Have_Completed_Execution();
How can i ensure that my method gets called only after all the other threads have completed execution.
You can use AutoResetEvent-s. Declare an AutoResetEvent array where all the threads can reach it.
AutoResetEvent[] events = new AutoResetEvent[numberOfThreads];
Start threads like this:
for (int i = 0; i < numberOfThreads; i++)
{
events[i] = new AutoResetEvent(false);
Thread thread = new Thread(start);
thread.Start(i);
}
WaitHandle.WaitAll(events);
call_This_Function_After_All_Threads_Have_Completed_Execution();
And finally don't forget to call the Set() method in the threads:
void start(object i)
{
//... do work
events[(int) i].Set();
}

Slow threading with XNA 3.1

I have a pretty strange problem with threading in XNA. I'm working on a PC with Q9400.
The code below is launched in the Update() function of XNA.
Stopwatch sw = new Stopwatch();
Thread[] threads = new Thread[2];
threads[0] = new Thread(() => Thread_UpdateDoodadsMovable(gameTime));
threads[1] = new Thread(() => Thread_UpdateDoodadsRotated(gameTime));
sw.Start();
foreach (Thread t in threads)
{
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
sw.Stop();
Console.WriteLine("A " + sw.ElapsedTicks);
sw.Reset();
Both threads are now 'empty' as the code is commented:
public void Thread_UpdateDoodadsRotated(GameTime gametime)
{
// level.UpdateDoodadsRotated(gameTime);
}
public void Thread_UpdateDoodadsMovable(GameTime gametime)
{
// level.UpdateDoodadsMovable(gametime);
}
The sw.ElapsedTicks returns between 7000 up to 10000. Can someone explain to me why is this happening?
I know that creating threads rather than taking them from ThreadPool is not the best way perfomance-wise but the thread creation takes a lot less time than ElapsedTicks return.

Multi thread worker thread status

I create my threads as
for (int i = 0; i < threadCount; i++)
{
Searcher src = new Searcher(i, this);
threads[i] = new Thread(new ThreadStart(src.getIpRange));
threads[i].Name = string.Format(i.ToString());
}
foreach (Thread t in threads)
{
t.Start();
}
with threadCount(= 100, 150, 255 etc...) but I can't learn how many threads working. on execute time.
and I want to control when all threads finishes their job. and give me a message like "All threads are dead, jobs completed..."
like backgroundWorker's RunWorkerCompleted event
Determining when all the threads are finished is simple.
for (int i = 0; i < threadCount; i++)
{
threads[i].Join();
}
Console.WriteLine("All threads are done!");
Can you elaborate on your other requirements?
You can check the ThreadState property of the Thread.
Might be better to use async methods. This gives you a WaitHandle object, and you can use WaitHandle.WaitAll to wait for all of your async methods to finish.
Here's an intro to asynchronous programming:
http://msdn.microsoft.com/en-us/library/aa719598%28v=VS.71%29.aspx
You definitely want to use the Task class for this or a higher-level concept like Parallel.ForEach. Using the Thread class directly is quite painful.
I recently wrote a blog post comparing various asynchronous approaches, listed in order from best (Task) to worst (Thread).
Here's an example using Task, demonstrating what you wanted to do:
// Start all tasks
var threads = new Task[threadCount];
for (int i = 0; i < threadCount; i++)
{
Searcher src = new Searcher(i, this);
threads[i] = Task.Factory.StartNew(src.getIpRange);
}
// How many are running right now?
var runningCount = threads.Count(x => x.Status == TaskStatus.Running);
// Register a callback when they have all completed (this does not block)
Task.Factory.ContinueWhenAll(threads, MyCallback);
Add a delegate to Searcher and pass it a callback method from your main thread that each thread will call when it finishes. As you launch each thread, add it to a Dictionary keyed by the thread's ManagedThreadId. When each thread finishes, the callback removes the thread from the Dictionary and checks to see if the count is zero.
Dictionary<int, Thread> activeThreads = new Dictionary<int, Thread>();
for (int i = 0; i < threadCount; i++)
{
Searcher src = new Searcher(i, this);
src.Done = new SearcherDoneDelegate(ThreadDone);
threads[i] = new Thread(new ThreadStart(src.getIpRange));
threads[i].Name = string.Format(i.ToString());
}
foreach (Thread t in threads)
{
lock (activeThreads)
{
activeThreads.Add(t.ManagedThreadId, t);
}
t.Start();
}
}
public void ThreadDone(int threadIdArg)
{
lock (activeThreads)
{
activeThreads.Remove(threadIdArg);
if (activeThreads.Count == 0)
{
// all done
}
}
}
public delegate void SearcherDoneDelegate(int threadIdArg);
public static object locker = new object();
public class Searcher
{
public SearcherDoneDelegate Done { get; set; }
public void getIpRange()
{
Done(Thread.CurrentThread.ManagedThreadId);
}
}
If you have more threads than you want to run at one time, put them into a Queue and peel them off as older threads finish (use the callback).
First, I have to point out that creating 100, 150, 255, etc. threads is probably not a good idea. You might be better off using the ThreadPool or Task class (if using .NET 4.0). Aside from that there are two well established methods for waiting until all threads complete.
Join the thread.
Thread.Join blocks until the target thread finishes.
for (int i = 0; i < threadCount; i++)
{
Searcher src = new Searcher(i, this);
threads[i] = new Thread(new ThreadStart(src.getIpRange));
threads[i].Name = string.Format(i.ToString());
}
foreach (Thread t in threads)
{
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
Use a CountdownEvent.
A CountdownEvent waits until its internal count reaches zero. This method is better suited if you want to use the ThreadPool. If you are not using .NET 4.0 you can get a really simple implementation over at Joe Albahari's website.
var finished = new CountdownEvent(1);
for (int i = 0; i < threadCount; i++)
{
finished.AddCount();
Searcher src = new Searcher(i, this);
threads[i] = new Thread(
() =>
{
try
{
src.getIpRange();
}
finally
{
finished.Signal();
}
}
threads[i].Name = string.Format(i.ToString());
}
foreach (Thread t in threads)
{
t.Start();
}
finished.Signal();
finished.WaitOne();
Why can't you use critical section protected single variable to control a number of active threads? Thread function can modify this variable (having entered critical section, of course).

Categories

Resources