I am new to C# and still learning the threading concept. I wrote a program which is as follows
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication17
{
class Program
{
static void Main(string[] args)
{
System.Threading.ThreadStart th1 = new System.Threading.ThreadStart(prnt);
Thread th = new Thread(th1);
th.Start();
bool t = th.IsAlive;
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i + "A");
}
}
private static void prnt()
{
for (int i = 0; i < 10; i ++)
{
Console.WriteLine(i + "B");
}
}
}
}
I am expecting an output like :-
1A
2A
1B
3A
2B...
as I believe that both main thread and newly created thread should be executing simultaneously.
But the output is ordered , first the prnt function is called and then the Main method for loop is executed.
maybe a cicle of 10 is not enough to see the two thread running at same time.
use a longer loop or put a Thread.Sleep (100) within cycle iteration.
Starting a thread is quite expensive. What it happens, probably, is that you Main loop get executed before thread loop start, due to the time required for a thread to start
I agree with previous answers you need to add Thread.Sleep(some seconds * 1000)
I recommend you read this article about thread
https://msdn.microsoft.com/ru-ru/library/system.threading.thread(v=vs.110).aspx
static void Main(string[] args)
{
Thread th = new Thread(prnt);
th.Start();
for (int i = 0; i < 10; i++)
{
//sleep one second
Thread.Sleep(1000);
Console.WriteLine(i + "A");
}
//join the basic thread and 'th' thread
th.Join();
}
private static void prnt()
{
for (int i = 0; i < 10; i++)
{
//sleep one second
Thread.Sleep(1000);
Console.WriteLine(i + "B");
}
}
Updated: A process is used to isolate applications and threads run in the context of that process.
This way, it makes easier for the OS to manage different apps, managing crashes and context switching (slots of time provided to each app to be executed by the CPU). The idea behind is simply run threads during a predefined slot of time, when the time permitted for an app to run is over, the CPU switches to other thread to be executed.
Use the Threading class for small asynchronous tasks in your applications.
See how in the following example you can create a new thread using the System.Threading namespace. Notice how t.Join() is called to wait for the new thread to finish.
Note that the Spleep(1) will force to change the context and that's is what makes the difference with you example. Try to change it back to zero and see the results.
using System;
using System.Threading;
namespace Chapter1
{
public static class Threads1
{
public static void ThreadMethod()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("ThreadProc: {0}", i);
Thread.Sleep(1);
}
}
public static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Main thread: Do some work.");
Thread.Sleep(1);
}
t.Join();
Console.Read();
}
}
}
// OUTPUT:
//Main thread: Do some work.
//ThreadProc: 0
//ThreadProc: 1
//Main thread: Do some work.
//ThreadProc: 2
//Main thread: Do some work.
//ThreadProc: 3
//Main thread: Do some work.
//ThreadProc: 4
//ThreadProc: 5
//ThreadProc: 6
//ThreadProc: 7
//ThreadProc: 8
//ThreadProc: 9
Related
I'm new to multi-threading, I want to achieve something like below using C#.
Thread 0 printed 0
Thread 1 printed 1
Thread 2 printed 2
Thread 3 printed 3
Thread 4 printed 4
Thread 5 printed 5
Thread 6 printed 6
Thread 7 printed 7
Thread 8 printed 8
Thread 9 printed 9
Thread 0 printed 10
Thread 1 printed 11
Thread 2 printed 12
Thread 3 printed 13
Thread 4 printed 14
Thread 5 printed 15
Thread 6 printed 16
Thread 7 printed 17
Thread 8 printed 18
Thread 9 printed 19
.
.
.
Thread 10 printed 99.
I have done something like this but of course, requirement is beyond.
class Program
{
static int count = 0; // the shared counter from 1 to 100
static void Main(string[] args)
{
Thread[] tr = new Thread[10]; // i have created 10 threads each one will print 10 cyclic values
string result = "";
int cc = 0;
while (cc!=10) {
for (int i = 0; i < 10; i++)
{
tr[i] = new Thread(new ThreadStart(printTill10));
tr[i].Start();
tr[i].Join();
}
cc++;
}
}
string s = "";
static void printTill10()
{
Console.WriteLine(++count+ "Printed by thread #"+
Thread.CurrentThread.ManagedThreadId);
}
}
I am confused either I should use a lock or something like monitor.wait or monitor.pulse etc.
Thanks for any help.
Do it like so:
First declare a variable count in the class so that it can be accessed by all threads. Also, create an object locker that will allow us to lock the count variable.
static int count;
static object locker;
Then, create the method that contains the code that the threads will all run:
static void printTill10()
{
while (true)
{
lock (locker)
{
if (count < 100)
{
count++;
Console.WriteLine(string.Format("Thread {0} printed {1}", Thread.CurrentThread.ManagedThreadId.ToString(), count.ToString()));
}
}
}
}
What this code does when run is the following:
Enters a while loop which loops forever.
Locks locker to make sure only one operation is being performed on count at a time.
Checks to see if count is under 100.
Increases count by one.
Prints a string exactly like the one you're trying to get (I used String.Format instead of concentration because its neater)
Simple right? This is the code that our threads will run. Now we can focus on the multithreading part.
static void Main()
{
count = 0; // Be sure to give count an initial value to prevent an exception from being thrown.
locker = new object();
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++)
{
threads[i] = new Thread(() => printTill100());
threads[i].Start();
}
Thread.Sleep(Timeout.Infinite);
}
Our Main does the following:
Gives an initial value to the count and locker variables.
Creates an array to put our threads in.
Enters a for loop which populates the array with threads and starts them.
Makes the main thread (the one code runs in by default) wait forever (specified by Timeout.Infinite. This last bit is an important one. By default, all code runs in a single thread called the main thread. If we don't tell it to wait, it will exit after the loop is done, closing the program. It will not wait until our other threads are finished.
There is just one thing you have missed while writing code in
printTill10()
method.
Just put one lock block in printTill10() method like this.
static void printTill10()
{
lock (_locker)
{
Console.WriteLine(++count + "Printed by thread #" + Thread.CurrentThread.ManagedThreadId);
}
}
and also declare locker object in the Pragram class like
static readonly object _locker = new object();
Here is the complete code
class Program
{
static int count = 0; // the shared counter from 1 to 100
static readonly object _locker = new object();
static void Main(string[] args)
{
Thread[] tr = new Thread[10]; // i have created 10 threads each one will print 10 cyclic values
string result = "";
int cc = 0;
while (cc != 10)
{
for (int i = 0; i < 10; i++)
{
tr[i] = new Thread(new ThreadStart(printTill10));
tr[i].Start();
tr[i].Join();
}
cc++;
}
}
string s = "";
static void printTill10()
{
lock (_locker)
{
Console.WriteLine(++count + "Printed by thread #" + Thread.CurrentThread.ManagedThreadId);
}
}
}
It will work as per your requirement. :)
After a continuous try, I got to complete the requirements of my task. Here is the code:
using System;
using System.Threading;
public class EntryPoint
{
static private int counter = 0;
static private object theLock = new Object();
static object obj = new object();
static private void count()
{
{
for (int i = 0; i < 10; i++)
{
lock (theLock)
{
Console.WriteLine("Count {0} Thread{1}",
counter++, Thread.CurrentThread.GetHashCode());
if (counter>=10)
Monitor.Pulse(theLock);
Monitor.Wait(theLock); } }}
}
static void Main()
{
Thread[] tr = new Thread[10];
for (int i = 0; i < 10; i++)
{
tr[i] = new Thread(new ThreadStart(count));
tr[i].Start();
}
}
}
Monitor maintains a ready queue in a sequential order hence I achieved what I wanted:
I'm looking for a fast way to let many worker threads wait for an event to continue and block the main thread until all worker threads are finished. I first used TPL or AutoResetEvent but since my calculation isn't that expensive the overhead was way too much.
I found a pretty interesting article concerning this problem and got great results (using only one worker thread) with the last synchronization solution (Interlocked.CompareExchange). But I don't know how to utilize it for a scenario where many threads wait for one main tread repeatedly.
Here is an example using single thread, CompareExchange, and Barrier:
static void Main(string[] args)
{
int cnt = 1000000;
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < cnt; i++) { }
Console.WriteLine($"Single thread: {stopwatch.Elapsed.TotalSeconds}s");
var run = true;
Task task;
stopwatch.Restart();
int interlock = 0;
task = Task.Run(() =>
{
while (run)
{
while (Interlocked.CompareExchange(ref interlock, 0, 1) != 1) { Thread.Sleep(0); }
interlock = 2;
}
Console.WriteLine($"CompareExchange synced: {stopwatch.Elapsed.TotalSeconds}s");
});
for (int i = 0; i < cnt; i++)
{
interlock = 1;
while (Interlocked.CompareExchange(ref interlock, 0, 2) != 2) { Thread.Sleep(0); }
}
run = false;
interlock = 1;
task.Wait();
run = true;
var barrier = new Barrier(2);
stopwatch.Restart();
task = Task.Run(() =>
{
while (run) { barrier.SignalAndWait(); }
Console.WriteLine($"Barrier synced: {stopwatch.Elapsed.TotalSeconds}s");
});
for (int i = 0; i < cnt; i++) { barrier.SignalAndWait(); }
Thread.Sleep(0);
run = false;
if (barrier.ParticipantsRemaining == 1) { barrier.SignalAndWait(); }
task.Wait();
Console.ReadKey();
}
Average results (in seconds) are:
Single thread: 0,002
CompareExchange: 0,4
Barrier: 1,7
As you can see Barriers' overhead seems to be arround 4 times higher! If someone can rebuild me the CompareExchange-scenario to work with multiple worker threads this would surely help, too!
Sure, 1 second overhead for a million calculations is pretty less! Actually it just interests me.
Edit:
System.Threading.Barrier seems to be the fastest solution for this scenario. For saving a double blocking (all workers ready for work, all workes finished) I used the following code for the best results:
while(work)
{
while (barrier.ParticipantsRemaining > 1) { Thread.Sleep(0); }
//Set work package
barrier.SignalAndWait()
}
It seems like you might want to use a Barrier to synchronise a number of workers with a main thread.
Here's a compilable example. Have a play with it, paying attention to when the output tells you that you can "Press <Return> to signal the workers to start".
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
static class Program
{
static void Main()
{
print("Main thread is starting the workers.");
int numWorkers = 10;
var barrier = new Barrier(numWorkers + 1); // Workers + main (controlling) thread.
for (int i = 0; i < numWorkers; ++i)
{
int n = i; // Prevent modified closure.
Task.Run(() => worker(barrier, n));
}
while (true)
{
print("***************** Press <RETURN> to signal the workers to start");
Console.ReadLine();
print("Main thread is signalling all the workers to start.");
// This will wait for all the workers to issue their call to
// barrier.SignalAndWait() before it returns:
barrier.SignalAndWait();
// At this point, all workers AND the main thread are at the same point.
}
}
static void worker(Barrier barrier, int workerNumber)
{
int iter = 0;
while (true)
{
print($"Worker {workerNumber} on iteration {iter} is waiting for barrier.");
// This will wait for all the other workers AND the main thread
// to issue their call to barrier.SignalAndWait() before it returns:
barrier.SignalAndWait();
// At this point, all workers AND the main thread are at the same point.
int delay = randomDelayMilliseconds();
print($"Worker {workerNumber} got barrier, now sleeping for {delay}");
Thread.Sleep(delay);
print($"Worker {workerNumber} finished work for iteration {iter}.");
}
}
static void print(string message)
{
Console.WriteLine($"[{sw.ElapsedMilliseconds:00000}] {message}");
}
static int randomDelayMilliseconds()
{
lock (rng)
{
return rng.Next(10000) + 5000;
}
}
static Random rng = new Random();
static Stopwatch sw = Stopwatch.StartNew();
}
}
I have a application where multiple threads have to wait on an event to indicate that new data is available in a list. My expectation was that I could use an AutoResetEvent, WaitOne on it in each thread, and then when the data is available Set the event.
However, because it is auto reset the first thread clears the event and doesn't release the other threads. Now I could presumably make it a manual reset and implement a counter, but my feeling is that this is a common problem and so there must be a standard way to do it, but searching the docs I couldn't find one.
Any help? Here is some sample code that doesn't release all the threads:
static AutoResetEvent eve = new AutoResetEvent(false);
static void Main(string[] args)
{
var threads = new List<Thread>();
for (int i = 0; i < 10; ++i)
{
int iCopy = i;
var t = new Thread(() => thread(iCopy));
threads.Add(t);
t.Start();
}
Console.WriteLine("Pausing");
Thread.Sleep(5000);
eve.Set();
foreach (var t in threads) t.Join();
Console.WriteLine("All done");
Console.ReadKey();
}
static void thread(int n)
{
eve.WaitOne();
Console.WriteLine("Thread {0}", n);
}
Just use the ManualResetEvent in the place of AutoRestEvent. There is not need for counter. I tried , it worked below is the code.
static ManualResetEvent eve = new ManualResetEvent(false);
static void Main(string[] args)
{
var threads = new List<Thread>();
for (int i = 0; i < 10; ++i)
{
int iCopy = i;
var t = new Thread(() => thread(iCopy));
threads.Add(t);
t.Start();
}
Console.WriteLine("Pausing");
Thread.Sleep(5000);
eve.Set();
foreach (var t in threads) t.Join();
Console.WriteLine("All done");
Console.ReadKey();
}
static void thread(int n)
{
eve.WaitOne();
Console.WriteLine("Thread {0}", n);
}
I have a application where multiple threads have to wait on an event to indicate that new data is available in a list. My expectation was that I could use an AutoResetEvent, WaitOne on it in each thread, and then when the data is available Set the event.
You have a bit of a XY Problem, however thankfully you included what your "X" was (Make the threads get new data from a list once it is available).
Based off of your description I think you would be better off using a BlockingCollection, you can spin up as many threads as you want and they will all block till new data is available, as soon as data is available they unblock and take data till there is none left then re-block.
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static BlockingCollection<int> _items = new BlockingCollection<int>();
static void Main(string[] args)
{
//Start up 4 threads
var threads = new Thread[4];
for (int i = 0; i < threads.Length; i++)
{
var iCopy = i;
threads[i] = new Thread(() => ProcessItems(iCopy));
threads[i].IsBackground = true;
threads[i].Start();
}
//Give the threads 5 items to process.
for (int i = 0; i < 5; i++)
{
_items.Add(i);
}
Console.WriteLine("All items queued, sleeping 2 seconds");
Thread.Sleep(2000);
//Give the threads 10 more items to process.
for (int i = 0; i < 10; i++)
{
_items.Add(i);
}
_items.CompleteAdding();
Console.WriteLine("Marked adding complete");
foreach (var t in threads) t.Join();
Console.WriteLine("All threads complete");
Console.ReadLine();
}
static void ProcessItems(int i)
{
var rnd = new Random(i);
foreach (var item in _items.GetConsumingEnumerable())
{
Console.WriteLine("Thread {0} Processing item {1}", i, item);
//Simulate a random amount work
Thread.Sleep(rnd.Next(100, 500));
}
}
}
}
If you really want to release all the waiting threads just once, use an array of semaphores, one for each thread. When you want them all to go, send one unit to each semaphore in a loop.
I am building a small application simulating a horse race in order to gain some basic skill in working with threads.
My code contains this loop:
for (int i = 0; i < numberOfHorses; i++)
{
horsesThreads[i] = new Thread(horsesTypes[i].Race);
horsesThreads[i].Start(100);
}
In order to keep the race 'fair', I've been looking for a way to make all newly created threads wait until the rest of the new threads are set, and only then launch all of them to start running their methods (Please note that I understand that technically the threads can't be launched at the 'same time')
So basically, I am looking for something like this:
for (int i = 0; i < numberOfHorses; i++)
{
horsesThreads[i] = new Thread(horsesTypes[i].Race);
}
Monitor.LaunchThreads(horsesThreads);
Threading does not promise fairness or deterministic results, so it's not a good way to simulate a race.
Having said that, there are some sync objects that might do what you ask. I think the Barrier class (Fx 4+) is what you want.
The Barrier class is designed to support this.
Here's an example:
using System;
using System.Threading;
namespace Demo
{
class Program
{
private void run()
{
int numberOfHorses = 12;
// Use a barrier with a participant count that is one more than the
// the number of threads. The extra one is for the main thread,
// which is used to signal the start of the race.
using (Barrier barrier = new Barrier(numberOfHorses + 1))
{
var horsesThreads = new Thread[numberOfHorses];
for (int i = 0; i < numberOfHorses; i++)
{
int horseNumber = i;
horsesThreads[i] = new Thread(() => runRace(horseNumber, barrier));
horsesThreads[i].Start();
}
Console.WriteLine("Press <RETURN> to start the race!");
Console.ReadLine();
// Signals the start of the race. None of the threads that called
// SignalAndWait() will return from the call until *all* the
// participants have signalled the barrier.
barrier.SignalAndWait();
Console.WriteLine("Race started!");
Console.ReadLine();
}
}
private static void runRace(int horseNumber, Barrier barrier)
{
Console.WriteLine("Horse " + horseNumber + " is waiting to start.");
barrier.SignalAndWait();
Console.WriteLine("Horse " + horseNumber + " has started.");
}
private static void Main()
{
new Program().run();
}
}
}
[EDIT] I just noticed that Henk already mentioned Barrier, but I'll leave this answer here because it has some sample code.
I'd be looking at a ManualResetEvent as a gate; inside the Thread, decrement a counter; if it is still non-zero, wait on the gate; otherwise, open the gate. Basically:
using System;
using System.Threading;
class Program
{
static void Main()
{
ManualResetEvent gate = new ManualResetEvent(false);
int numberOfThreads = 10, pending = numberOfThreads;
Thread[] threads = new Thread[numberOfThreads];
ParameterizedThreadStart work = name =>
{
Console.WriteLine("{0} approaches the tape", name);
if (Interlocked.Decrement(ref pending) == 0)
{
Console.WriteLine("And they're off!");
gate.Set();
}
else gate.WaitOne();
Race();
Console.WriteLine("{0} crosses the line", name);
};
for (int i = 0; i < numberOfThreads; i++)
{
threads[i] = new Thread(work);
threads[i].Start(i);
}
for (int i = 0; i < numberOfThreads; i++)
{
threads[i].Join();
}
Console.WriteLine("all done");
}
static readonly Random rand = new Random();
static void Race()
{
int time;
lock (rand)
{
time = rand.Next(500,1000);
}
Thread.Sleep(time);
}
}
I am trying to understand threading concepts in .Net.
I am unable to use Yield() method. I want the control to go to a parallel thread when i becomes divisible by 10.
Please help.
Below is my sample code:
class ThreadTest
{
//Index i is declared as static so that both the threads have only one copy
static int i;
static void Main(string[] args)
{
Thread t = new Thread(WriteY);
i = 0;
//Start thread Y
t.Start();
//Do something on the main thread.
for (; i < 100; i++)
{
if (i % 10 == 0)
{
//Simulate Yield() function
Thread.Sleep(0);
Console.WriteLine("The X thread");
}
Console.Write(i + ":X ");
}
Console.ReadKey(true);
}
static void WriteY()
{
for (; i < 100; i++)
{
if (i % 10 == 0)
{
//Simulate Yield() function
Thread.Sleep(0);
Console.WriteLine("The Y thread");
}
Console.Write(i + ":Y ");
}
}
}
I get the compile time error:
System.Threading.Thread does not contain a definition for 'Yield'
Answered by Tudor. This method will only work on .Net 4.0 and upwards.
Ideally I would want one thread to start and want each thread to execute for 10 incremented of i each. With my current method, I either get all 'X' or all 'Y'.
Edit:
With inputs from Tudor and TheHe - I have been able to get alternate X and Y. The crux of the problem was usage of lock object. But the output of this code is not predictable.
Thread.Yield will simply enable the scheduler to select a different thread that is ready to run:
Causes the calling thread to yield execution to another thread that is
ready to run on the current processor. The operating system selects
the thread to yield to.
If other threads in your application are also waiting on that lock, you can yield all you want, they won't get a chance to run.
Btw, Yield is a .NET 4.0+ method. Make sure you're not targeting an earlier version.
Edit: IMO, to do what you want you should use events:
class Test
{
//Index i is declared as static so that both the threads have only one copy
static int i;
static AutoResetEvent parentEvent = new AutoResetEvent(true);
static AutoResetEvent childEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
Thread t = new Thread(WriteY);
i = 0;
//Start thread Y
t.Start();
// Print X on the main thread
parentEvent.WaitOne();
while (i < 100)
{
if (i % 10 == 0)
{
childEvent.Set();
parentEvent.WaitOne();
}
Console.Write(i + ":Y ");
i++;
}
t.Join();
}
static void WriteY()
{
childEvent.WaitOne();
while (i < 100)
{
if (i % 10 == 0)
{
parentEvent.Set();
childEvent.WaitOne();
}
Console.Write(i + ":X ");
i++;
}
}
}
Forget Thread.Yield; that is unrelated to what you are trying to do. Ultimately, you have a lock, which uses Monitor to synchronize access. Inside the lock, your thread exclusively has access. What you need to do is relinquish the lock temporarily; the way you do that is with Monitor.Wait. However, if you Wait, you also end up in the "waiting" queue rather than the "ready" queue, so in order to make sure that each thread gets attention, we also need to Pulse, both before the Wait, and also at the end (to make sure both threads get chance to exit). Here we go:
using System.Threading;
using System;
class ThreadTest
{
//Index i is declared as static so that both the threads have only one copy
static int i;
//The lock object
static readonly object locker = new object();
static void Main(string[] args)
{
Thread t = new Thread(WriteY);
i = 0;
//Start thread Y
t.Start();
lock (locker)
{
// Print X on the main thread
for (; i < 100; i++)
{
if (i % 10 == 0)
{
Monitor.PulseAll(locker); // move any "waiting" threads to the "ready" queue
Monitor.Wait(locker); // relinquish the lock, and wait for a pulse
Console.WriteLine("The X thread");
}
Console.Write(i + ":X ");
}
Monitor.PulseAll(locker);
}
Console.ReadKey(true);
}
static void WriteY()
{
lock (locker)
{
for (; i < 100; i++)
{
if (i % 10 == 0)
{
Monitor.PulseAll(locker); // move any "waiting" threads to the "ready" queue
Monitor.Wait(locker); // relinquish the lock, and wait for a pulse
Console.WriteLine("The Y thread");
}
Console.Write(i + ":Y ");
}
Monitor.PulseAll(locker); // move any "waiting" threads to the "ready" queue
}
}
}
from my point of view, you're locking "locker" in current thread and want to yield the current task to an other thread...
the lock is held by the first thread all the time -- it can't work?!
you have to manually lock the objects if you want to use multiple threads...