I start threads exactly like book says:
for (int i = 1; i <= 4; i++) {
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), i);
}
ThreadMethod looks like:
static void ThreadMethod(object input) {
Console.WriteLine(input + " thread started");
//do some stuff for, like, 400 milliseconds
Console.WriteLine(input + " thread completed");
}
In some reason 2 thread starts only after 1 is completed (in this moment all work is already done and 2-4 thread just start and stop doing nothing).
What could be wrong? Ask anything what could help solve this problem.
I don't use any synchronization classes.
If it's matter, i have 2 core processor.
Your ThreadMethod just runs too fast. Everything is right with your code except if possible you should switch from ThreadPool to new abstractions like Task.Run.
Actually, as i made ThreadMethod to do much longer stuff, another threads started after some time but it don't worked in one time but just switches from thread to thread. Looks like i have to use another tool.
A TreadPool has a maximum number of threads that it can use. See ThreadPool.GetMaxThread and SetMaxThread. It is probably equal to the number of available cores by default.
For CPU intensive work it makes sense since you would actually lower performance by using more threads than you have cores. However, for slow jobs such as I/O intensive jobs, many threads can run in parallel to avoid blocking and wait until the I/O is complete. Example: Grabing several files at a time from various FTP servers.
Related
I'm writing an application that should simulate the behavior of a PLC. This means I have to run several threads making sure only one thread at a time is active and all others are suspended.
For example:
thread 1 repeats every 130ms and blocks all other threads. The effective runtime is 30ms and the remaining 100ms before the thread restarts can be used by other threads.
thread 2 repeats every 300ms and blocks all threads except for thread 1. The effective runtime is 50ms (the remaining 250ms can be used by other threads). Thread 2 is paused until thread 1 has finished executing code (the remaining 100ms of thread 1) and once thread 1 is asleep it resumes from where it has been paused
thread 3 repeats every 1000ms. The effective runtime is 100ms. This thread continues execution only if all other threads are suspended.
The highest priority is to complete the tasks before they are called again, otherwise I have to react, therefore a thread that should be blocked should not run until a certain point, otherwise multicore processing would elaborate the code and only wait to pass the results.
I read several posts and learned that Thread.suspend is not recomended and semaphore or monitor operations mean that the code is executed until a specific and fixed point in the code while I have to pause the threads exactly where the execution has arrived when an other thread (with higher "priority") is called.
I also looked at the priority setting but it doesn't seem to be 100% relevant since the system can override priorities.
Is there a correct or at least solid way to code the blocking mechanism?
I don't think you need to burden yourself with Threads at all. Instead, you can use Tasks with a prioritised TaskScheduler (it's not too hard to write or find by googling).
This makes the code quite easy to write, for example the highest priority thread might be something like:
while (!cancellationRequested)
{
var repeatTask = Task.Delay(130);
// Do your high priority work
await repeatTask;
}
Your other tasks will have a similar basic layout, but they will be given a lower priority in the task scheduler (this is usually handled by the task scheduler having a separate queue for each of the task priorities). Once in a while, they can check whether there is a higher priority task, and if so, they can do await Task.Yield();. In fact, in your case, it seems like you don't even need real queues - that makes this a lot easier, and even better, allows you to use Task.Yield really efficiently.
The end result is that all three of your periodic tasks are efficiently run on just a single thread (or even no thread at all if they're all waiting).
This does rely on coöperative multi-tasking, of course. It's not really possible to handle full blown real-time like pre-emption on Windows - and partial pre-emption solutions tend to be full of problems. If you're in control of most of the time spent in the task (and offload any other work using asynchronous I/O), the coöperative solution is actually far more efficient, and can give you a lot less latency (though it really shouldn't matter much).
I hope I don't missunderstand your question :)
One possibility to your problem might be to use a concurrent queue: https://msdn.microsoft.com/de-de/library/dd267265(v=vs.110).aspx
For example you create a enum to control your state and init the queue:
private ConcurrentQueue<Action> _clientActions ;
private enum Statuskatalog
{
Idle,
Busy
};
Create a timer to start and create a timerfunktion.
Timer _taskTimer = new Timer(ProcessPendingTasks, null, 100, 333);
private void ProcessPendingTasks(object x)
{
_status = Statuskatalog.Busy;
_taskTimer.Change(Timeout.Infinite, Timeout.Infinite);
Action currentTask;
while( _clientActions.TryDequeue( out currentTask ))
{
var task = new Task(currentTask);
task.Start();
task.Wait();
}
_status=Statuskatalog.Idle;
}
Now you only have to add your tasks as delegates to the queue:
_clientActions.Enqueue(delegate { **Your task** });
if (_status == Statuskatalog.Idle) _taskTimer.Change(0, 333);
On this base, you can manage your special requirements you were asking for.
Hope this was, what you were searching for.
private static void Main(string[] args)
{
for (int i = 0; i < 1000; i++)
{
Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
Console.WriteLine("hej");
Thread.Sleep(10000);
});
}
Console.ReadLine();
}
Why this code won't print 1000 times "hej" after one second? Why Thread.Sleep(10000) has an impact on code behavior?
Factory.StartNew effectively delegates the work to ThreadPool.
Threadpool will create number of threads immediately to respond the request as long as threads count is less than or equal to processor count. Once it reaches processor count, threadpool will stop creating new threads immediately. That makes sense, because creating number of threads more than processor count introduces Thread scheduling overhead and returns nothing.
Instead it will throttle the creation of threads. It waits for 500 ms to see if any work still pending and no threads to process the request. If pending works are there, it will introduce a new thread(only one). This process keeps on going as long as you have enough works to do.
When work queue's traffic is cleared, threadpool will destroy the threads. And above mentioned process keeps on going.
Also, There is a max limit for number of threads threadpool can run simultaneously. If you hit that, threadpool will stop creating more threads and wait for previous work items to complete, So that it can reuse the existing thread.
That's not the end of story, It is convoluted! These are few decisions taken by ThreadPool.
I hope now that will be clear why you see what you see.
There are a multitude of factors that would alter the result.
Some being (but not limited to):
The inherent time for the iteration of the loop
The size of the thread pool
Thread management overhead
The way you code behaves is intended behaviour. You wait 1000 milliseconds to print hej and after printing you do Thread.sleep for another 10000 millesconds. If you want to print 1000 times hej after one second remove Thread.sleep(10000).
I have an application that polls some devices each x second,
my implementation is based on one thread for each device.
Each thread is implemented in this way
while(true){
stopWatch.Start();
//dowork
stopWatch.Stop();
time = (int)(delay - stopWatch.ElapsedMilliseconds);
stopWatch.Reset();
sleep(time);
}
Now it's the correct way or i should implement a Timer that fire each x second and create a new Task?
PS: each device has is polling code
Using a thread that is looping is less work for you and results in clearer code. So I recommend you do just that.
Use timers or async sleeping (Task.Delay + async/await) if you have many threads or need to conserve resources.
Using a single thread that sleeps between the polls seems like the best way to do this. It will poll the devices needed after the sleep. Since you are doing a single repeated task that is likely to never end until the program ends I don't think that using a task really fits this situation even though it could be used.
I used Task like below but there is no performance gain. I checked my method which executes in 0-1 seconds but with Task(30 Tasks), it takes 5-12 seconds. Can anyone guide if I have done any mistake. I want to run 30 parallel and expect 30 done in max 2 seconds.
Here is my code:
Task[] tasks = new Task[30];
for (int p = 0; p <= dstable.Tables[0].Rows.Count - 1; p++)
{
MethodParameters newParameter = new MethodParameters();
newParameter.Name = dstable.Tables[0].Rows[p]["Name"].ToString();
tasks[p] = Task.Factory.StartNew(() => ParseUri(newParameter));
Application.DoEvents();
}
try
{
Task.WaitAll(tasks);
//Console.Write("task completed");
}
catch (AggregateException ae)
{
throw ae.Flatten();
}
There are some major problems in your thinking.
does your PC have 30 Cores, so that every core can exactly takes one task? I don't think so
starting a seperate thread also takes some time.
with every concurrent thread more overhead is generated.
Can your problem be solved faster by starting more threads? This is only the case, when all threads do different tasks, like reading from disk, quering a database, computing something, etc.. 10 threads that do all "high-performance" tasks on the cpu, won't give an boost, quite contrary to, because every thread needs to clean up his mess, before he can give some cpu time to the next thread, and that one needs to clean up his mess too.
Check this link out
http://msdn.microsoft.com/en-us/library/ms810437.aspx
You can use the TPL
http://msdn.microsoft.com/en-us/library/dd460717.aspx
they try to guaranty the maximum effect from parallel threads.
Also I recommend this book
http://www.amazon.com/The-Multiprocessor-Programming-Maurice-Herlihy/dp/0123705916
When you really want to solve your problem in under 2 seconds, buy more CPU power ;)
I think you may have missing the main point of using thread.
Creating many threads may lead to more complexity by increasing OS over-head. (Context switching)
Also it will be much harder to manage your execution of code and harder to find and fix bugs if there is any.
Usage of thread may give you advantage when there is
Task need to be perform simultaneously
Building responsive UI
in console because threads sleep with randoms it will show the order of threads
3,2,1 or 1,2,3 or ...
how can I have fixed order?
and why when I set priority it doeasn't effect the code?
// ThreadTester.cs
// Multiple threads printing at different intervals.
using System;
using System.Threading;
namespace threadTester
{
// class ThreadTester demonstrates basic threading concepts
class ThreadTester
{
static void Main(string[] args)
{
// Create and name each thread. Use MessagePrinter's
// Print method as argument to ThreadStart delegate.
MessagePrinter printer1 = new MessagePrinter();
Thread thread1 =
new Thread(new ThreadStart(printer1.Print));
thread1.Name = "thread1";
MessagePrinter printer2 = new MessagePrinter();
Thread thread2 =
new Thread(new ThreadStart(printer2.Print));
thread2.Name = "thread2";
MessagePrinter printer3 = new MessagePrinter();
Thread thread3 =
new Thread(new ThreadStart(printer3.Print));
thread3.Name = "thread3";
Console.WriteLine("Starting threads");
// call each thread's Start method to place each
// thread in Started state
thread1.Priority = ThreadPriority.Lowest;
thread2.Priority = ThreadPriority.Normal;
thread3.Priority = ThreadPriority.Highest;
thread1.Start();
thread2.Start();
thread3.Start();
Console.WriteLine("Threads started\n");
Console.ReadLine();
} // end method Main
} // end class ThreadTester
// Print method of this class used to control threads
class MessagePrinter
{
private int sleepTime;
private static Random random = new Random();
// constructor to initialize a MessagePrinter object
public MessagePrinter()
{
// pick random sleep time between 0 and 5 seconds
sleepTime = random.Next(5001);
}
// method Print controls thread that prints messages
public void Print()
{
// obtain reference to currently executing thread
Thread current = Thread.CurrentThread;
// put thread to sleep for sleepTime amount of time
Console.WriteLine(
current.Name + " going to sleep for " + sleepTime);
Thread.Sleep(sleepTime);
// print thread name
Console.WriteLine(current.Name + " done sleeping");
} // end method Print
} // end class MessagePrinter
}
You use threads precisely because you do not care about having things happen in a particular order, but want either:
At the same time, if there are enough cores to allow them to happen together.
With some making progress while others are waiting for something.
Interleaved with paying attention to I/O or user-input, so as to continue being responsive.
In each of these cases, you just don't care that you don't know just which bit of what will happen when.
However:
You may still care about the order of certain sequences. In the simplest case, you just have these things happen in sequence within the same thread, while other things happen in other threads. More complicated cases can be served by chaining tasks together.
You may want the results from different threads to finally be put into a different order. The simplest approach is to put them all into order after they've all finished, though you can also sort results as they come (tricky though).
For ideal performance, there should be one thread running on each core (or possibly two on a hyperthreaded core, but that has further complications) at all times. Let's say you have a machine with 4 cores and 8 tasks you need done.
If the tasks involved a lot of waiting on I/O, then four will start, each will reach a point where it's waiting on that I/O, and allow one of the other tasks to make some progress. Chances are that even with the number of tasks being twice the number of cores, it'll still end up with plenty of idle time. If each task was going to take 20seconds, then doing them on different threads will probably have them all done in just a little over 20seconds, since all of them were spending most of their 20seconds waiting on something else.
If you are doing tasks that keep the CPU busy all the time (not much waiting for memory and certainly not for I/O) then you will be able to have four such tasks going at a time, while the others are waiting for them to either finish, or give up their slice of time. Here if each took 20seconds, the best you could hope for is a total time of about 40seconds (and that's assuming that no other thread from any process on the system wants the CPU, that you've a perfect lack of overhead in setting up the threads, etc).
In cases where there is more work to do (active work to do, rather than waiting for I/O to complete, another thread to release a lock, etc.) than cores, the OSs scheduler will swap around between different threads that want to be active. The exact details differs from OS to OS (different Windows versions, including some important differences between desktop and server set ups, take different approaches, different Linux versions with some particularly big changes from 2.4 to 2.6 and different Unixes, etc. all have different strategies).
One thing they all have in common is the common goal of making sure stuff gets done.
Thread priorities and process priorities are ways to influence this scheduling. With Windows, whenever there's more threads waiting to work than cores to work, those of the highest priority get given CPU time in a round-robin fashion. Should there be no threads of that priority, then those of the next lowest are given CPU time, then the next and so on.
This is a great way to have things grind things to a halt. It can lead to complications where a thread that was given high priority (presumably because it's work is considered particularly crucial) is waiting on a thread given low priority (presumably because its work is considered less important and one wants it to always cede time to the others), and the low-priority thread keeps not being given CPU time, because there's always more threads of higher priority than available cores. Hence the supposedly high-priority thread gets no CPU time at all.
To fix this situation, windows will occasionally promote the threads that haven't run in a long time. This fixes things, but now means you've got the supposedly low-priority threads bursting along as super-high priority to the detriment not just of the rest of the application but also the rest of the sytem.
(One of the best things about having a multi-core system, is it means your computing experience is less affected by people who set the priority of threads!)
If you use a debugger to stop a multi-threaded .NET application and examine the threads you'll probably find that all of them are at normal except for one at highest. This one at highest will be the finalizer thread and its running at highest priority is one of the reasons its important that finalizers should not take a long time to execute - having work done at highest priority is a bad thing and while it is justified in this case, it must end as soon as possible.
At least 95% of all other cases where someone sets the priority of a thread is a logical bug - it'll do nothing most of the time and allows things to get very messed up the rest. They can be used well (or we wouldn't have that ability at all), but should definitely be put in the "advanced techniques" category. (I like to spend my free time experimenting with multi-threading techniques that would count as excessive and premature optimisation most of the time, and I still hardly ever touch priorities).
In your example, priority will have little effect because each thread spends most of its time sleeping, so whichever thread does want CPU time can get it for the few nano-seconds it needs to run. What it could do though is cause the whole thing to become needlessly slower should you run it on a machine where the cores are also busy with other normal threads. In this case thead1 wouldn't get any CPU time at first (because there's always a higher priority thread that wants the CPU), then after 3seconds the scheduler would realise its been starved for an eternity the terms of CPU speeds (9billion CPU cycles or so) and give it a burst to highest priority for long enough to let it screw with the timing of vital windows services! Luckily it then sleeps and then does a minute amount of work before finishing, so it does no harm, but if it was doing anything real it could have some really nasty effects on the entire system's performance.
You can't guarantee when windows will execute a particular thread. You can make suggestions to the OS (I.E. the priority level) but ultimately Windows will decide when, what and where.
If you want to ensure that 1 starts before 2 which in turns starts before 3 you should make thread 1 start thread 2 and thread 2 start thread 3.
Threads are considered lightweight processes, in that they run completely independent of each other. If your task relies heavily on the order in which threads execute, you probably shouldn't be using threads.
Otherwise, you need to look at the thread synchronization constructs that the .NET framework provides.
You can not synchronize threads like this. If you need the work done in a certain order, don't use seperate threads, or use ResetEvents or something similar.
Thread scheduling is never guaranteed. Order is never preserved unless you explicitly force it through your code via locks/etc.