c# Thread issue [duplicate] - c#

This question already has answers here:
Is .NET's StringBuilder thread-safe
(3 answers)
Closed 5 years ago.
using System;
using System.Threading;
using System.Text;
class ThreadTest
{
static StringBuilder sb = new StringBuilder();
static void Main()
{
Thread t = new Thread(WriteY);
t.Start();
for(int i = 0; i < 1000; i++)
{
sb.Append("x");
}
Console.WriteLine(sb.ToString());
}
private static void WriteY()
{
for (int i = 0; i < 1000; i++)
{
sb.Append("y");
}
}
}
output:
{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy}
Question:
Why does 'x' appear before 'y'?
StringBuilder is Accept only one Thread?
Why does not appear like this "xyxyxyxyx xyxyxyxy"?

Questions 1 and 3 are both related to the time slicing of the Windows scheduler. According to the Windows 2000 Performance Guide, a time slice on x86 processors is about 30 ms. That may have changed since Windows 2000, but should still be in this order of magnitude. Hence, t.Start() only adds the new thread to the scheduler but does not immediately trigger a context switch to it. The main thread has still the remaining part of its time slice, which obviously is enough time to print the 'x' 1,000 times.
Furthermore, when the new thread is actually scheduled, it has a whole time slice to print out 'y'. As this is plenty of time, you don't get the pattern "xyxyxy", but rather 'x's until the time slice of the main thread runs out and then 'y's until the end of the time slice of the new thread and then 'x's again. (At least if there are enough 'x's and 'y's to be printed, which, according to Simon's comment is the case with 10,000 'x's and 'y's.)
Question 2 is answered by the MSDN page on the StringBuilder. Under the topic "Thread Safety" it is written that "Any public static ( Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe." As the Append method is an instance method, you cannot call this reliably from different threads in parallel without further synchronization.

Is this what you are looking for?
class Program
{
static StringBuilder sb = new StringBuilder();
static void Main()
{
Thread t = new Thread(WriteY);
t.Start();
for (int i = 0; i < 1000; i++)
{
//Console.Write("x");
sb.Append("x");
Thread.Sleep(10);
}
//t.Join();
Console.WriteLine(sb.ToString());
}
private static void WriteY()
{
for (int i = 0; i < 1000; i++)
{
//Console.Write("y");
sb.Append("y");
Thread.Sleep(10);
}
}
}
Why does 'x' appear before 'y'?
Because the main thread is not blocked at any point and continuing its execution before the resources are granted to other thread that is printing y
StringBuilder is Accept only one Thread?
No that is not the case. Run example below.
Why does not appear like this "xyxyxyxyx xyxyxyxy"?
there is not much work so, to get that random result you need to increase the duration which is demonstrated by using sleep.
Update: in your above example you can see the randomness if you increase your loop to 100000 or greater. and you also need to add t.Join() otherwise you thread may not yield the work.

Related

How to achieve 100% cpu load with c# code [duplicate]

This question already has answers here:
thread get 100% CPU very fast
(5 answers)
Closed 4 years ago.
I have a task to get a piece of c# code to make my CPU go 100% consistently. I have tried infinite loops, big integer calculations, concatenation of numerous very long strings.... everything either goes to 100% for a few moments and then down to like 60% or doesn't go to 100% at all.
Is there a simple piece of code that can achieve this?
Also using Windows 10
You would want to implement threading for this as was previously stated. Your thread would call a method that contains a while(true) loop. For example:
Random rand = new Random()
List<Thread> threads = new List<Thread>();
public void KillCore()
{
long num = 0;
while(true)
{
num += rand.Next(100, 1000);
if (num > 1000000) { num = 0; }
}
}
public void Main()
{
while (true)
{
threads.Add( new Thread( new ThreadStart(KillCore) ) );
}
}
You don't have to add the threads to a list but you may want to if you somewhere down the road want to call Thread.Abort() to kill them off. To do this you would need a collection of some sort to iterate through and call the Abort() method for every Thread instance in the collection. The method to do that would look as follows.
public void StopThreads()
{
foreach (Thread t in threads) { t.Abort(); }
}
use parallel for to maximize the CPU Cores usage and get the best of threading , inside each thread create an infinite loop using while(true) and congratulations
you have **** your CPU :D

Will all the worker threads get generated at once?

Is anyone out there who can explain me the flow of this code?
I wonder how main thread generates worker threads, what I know is:
As soon as main thread calls .start method it creates a new thread.
But I have a confusion how the behavior changes when it comes to looping multiple threads in main.
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();
}
static private void count()
{
for (int i = 0; i < 10; ++i)
{
lock (theLock)
{
Console.WriteLine("Count {0} Thread{1}",
counter++, Thread.CurrentThread.GetHashCode());
}
}
Is there a good way to debug and track your multithreaded program. after google it out I found tracking thread window in debug mood, but I couldn't find it useful even after given custom names to threads.
I just can't understand the flow, how threads being launched, how they work all together etc as breakpoints seem no effect in multi-threaded application. (At least in my case.)
I want this output 1 printed by Thread : 4551 [ThreadID] 2 printed by
Thread : 4552 3 printed by Thread : 4553 4 printed by Thread : 4554 5
printed by Thread : 4555 6 printed by Thread : 4556 7 printed by
Thread : 4557 8 printed by Thread : 4558 9 printed by Thread : 4559 10
printed by Thread : 4560 11 printed by Thread : 4551 [ Same Thread Id
Appears again as in 1] 12 printed by Thread : 4552
I'll try to describe what your code is doing as it interacts with the threading subsystem. The details I'm giving are from what I remember from my OS design university classes, so the actual implementation in the host operating system and/or the CLR internals may vary a bit from what I describe.
static void Main()
{
Thread[] tr = new Thread[10];
for (int i = 0; i < 10; i++)
{
tr[i] = new Thread(new ThreadStart(count));
// The following line puts the thread in a "runnable" thread list that is
// managed by the OS scheduler. The scheduler will allow threads to run by
// considering many factors, such as how many processes are running on
// the system, how much time a runnable thread has been waiting, the process
// priority, the thread's priority, etc. This means you have little control
// on the order of execution, The only certain fact is that your thread will
// run, at some point in the near future.
tr[i].Start();
// At this point you are exiting your main function, so the program should
// end, however, since you didn't flag your threads as BackgroundThreads,
// the program will keep running until every thread finishes.
}
static private void count()
{
// The following loop is very short, and it is probable that the thread
// might finish before the scheduler allows another thread to run
// Like user2864740 suggested, increasing the amount of iterations will
// increase the chance that you experience interleaved execution between
// multiple threads
for (int i = 0; i < 10; ++i)
{
// Acquire a mutually-exclusive lock on theLock. Assuming that
// theLock has been declared static, then only a single thread will be
// allowed to execute the code guarded by the lock.
// Any running thread that tries to acquire the lock that is
// being held by a different thread will BLOCK. In this case, the
// blocking operation will do the following:
// 1. Register the thread that is about to be blocked in the
// lock's wait list (this is managed by a specialized class
// known as the Monitor)
// 2. Remove the thread that is about to be blocked from the scheduler's
// runnable list. This way the scheduler won't try to yield
// the CPU to a thread that is waiting for a lock to be
// released. This saves CPU cycles.
// 3. Yield execution (allow other threads to run)
lock (theLock)
{
// Only a single thread can run the following code
Console.WriteLine("Count {0} Thread{1}",
counter++, Thread.CurrentThread.GetHashCode());
}
// At this point the lock is released. The Monitor class will inspect
// the released lock's wait list. If any threads were waiting for the
// lock, one of them will be selected and returned to the scheduler's
// runnable list, where eventually it will be given the chance to run
// and contend for the lock. Again, many factors may be evaluated
// when selecting which blocked thread to return to the runnable
// list, so we can't make any guarantees on the order the threads
// are unblocked
}
}
Hopefully things are clearer. The important thing here is to acknowledge that you have little control of how individual threads are scheduled for execution, making it impossible (without a fair amount of synchronization code) to replicate the output you are expecting. At most, you can change a thread's priority to hint the scheduler that a certain thread must be favored over other threads. However, this needs to be done very carefully, as it may lead to a nasty problem known as priority inversion. Unless you know exactly what you are doing, it is usually better not to change a thread's priority.
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:
Cheers!

Maximum number of Threads available to Tasks

I'm Trying to get my head around the async-await functionality within C#. I've written the below code to run several tasks asynchronously - currently all they do is raise an event after a certain amount of time.
public class Program
{
public static Stopwatch Watch = new Stopwatch();
public static void Main(string[] args)
{
AsyncClass asyncClass = new AsyncClass();
asyncClass.WaitSecondsAsyncCompleted += asyncClass_WaitSecondsAsyncCompleted;
List<Task> tasks = new List<Task>();
Watch.Start();
for (int i = 1; i < 6; i++)
{
tasks.Add(asyncClass.WaitSecondsAsync(i, Watch));
}
Task.WaitAll(tasks.ToArray());
Console.ReadLine();
}
private static void asyncClass_WaitSecondsAsyncCompleted(int i)
{
Console.WriteLine("{1} : Async Method Called: waited for {0} seconds", i, Watch.ElapsedMilliseconds);
}
}
public class AsyncClass
{
public event Action<int> WaitSecondsAsyncCompleted;
public async Task WaitSecondsAsync(int x, Stopwatch watch)
{
await Task.Run(() =>
{
Thread.Sleep(x * 500);
});
if (WaitSecondsAsyncCompleted != null)
{
WaitSecondsAsyncCompleted(x);
}
}
}
I'd expect a task to be completed roughly once every half a second - however this is not quite what I see. Instead the first four tasks complete on time but the final task has an extra half second delay:
This seems very strange - and the only thing I can think of is that there is a limit on the number of threads that are available to a task and that this is limit is very small and so the fifth task is having to wait for the first task to complete before it can start.
I added some extra output and increased the number of tasks to try and gain more information but I can make little sense of it - the output seems to be deterministic, some threads are reused, but also new ones are used. The delay on tasks being completed also seems to continue to grow (for instance for Task 10 I'd expect it to complete after 5 seconds, instead it stops after 8 seconds). I've attached the output below.
What I'd like to know:
Does anyone know what's going on in this particular example?
Is the limit on threads available small enough to have an effect here?
I presume asynchronous tasks are not guaranteed to start immediately, but there appears to be some other deterministic process going on here, which I hadn't expected. Does anyone know what that is?
Edit
Note that this question does not ask about the maximum number of tasks that can be run (Max tasks in TPL?) but rather how an effect can be seen when running as few as 5 tasks. I was under the impression that default threadPool contained many more threads than this.
So, it turns out that the issue I was seeing had to do with the threadpool size. This is apparently initially set to the number of cores of the machine (https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getminthreads%28v=vs.110%29.aspx).
It can be increased, and doing so means that more of the tasks are initially run simultaneously (https://msdn.microsoft.com/en-us/library/system.threading.threadpool.setminthreads%28v=vs.110%29.aspx)

Handle leak in .Net threads

This has actually bitten me a couple times. If you do simple code like this:
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 1000000; i++)
{
Thread CE = new Thread(SendCEcho);
CE.Priority = ThreadPriority.Normal;
CE.IsBackground = true;
CE.Start();
Thread.Sleep(500);
GC.Collect();
}
}
private void SendCEcho()
{
int Counter = 0;
for (int i = 0; i < 5; i++)
{
Counter++;
Thread.Sleep(25);
}
}
Run this code and watch the handles fly! Thread.Sleep is so you can shut it down and it doesn't take over you computer. This should guarantee that the thread launched dies before the next thread is launched. Calling GC.Collect(); does nothing. From my observation this code loses 10 handles every refresh to the task manager at normal refresh.
It doesn't matter what is in the void SendCEcho() function, count to five if you want. When the thread dies there is one handle that does not get cleaned up.
With most programs this doesn't really matter because they do not run for extended periods of time. On some of the programs I've created they need to run for months and months on end.
If you exercise this code over and over, you can eventually leak handles to the point where the windows OS becomes unstable and it will not function. Reboot required.
I did solve the problem by using a thread pool and code like this:
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadJobMoveStudy));
My question though is why is there such a leak in .Net, and why has it existed for so long? Since like 1.0? I could not find the answer here.
You're creating threads that never end. The for loop in SendCEcho never terminates, so the threads never end and thus cannot be reclaimed. If I fix your loop code then the threads finish and are reclaimed as expected. I'm unable to reproduce the problem with the code below.
static void SendCEcho()
{
int Counter = 0;
for (int i = 0; i < 5; i++)
{
Counter++;
Thread.Sleep(25);
}
}
for (int i = 0; i < 5 + i++; )
Fairly bizarre typo, you have not re-created your real problem. There is one, a Thread object consumes 5 operating system handles, its internal finalizer releases them. A .NET class normally has a Dispose() method to ensure that such handles can be released early but Thread does not have one. That was courageous design, such a Dispose() method would be very hard to call.
So having to rely on the finalizer is a hard requirement. In a program that has a "SendEcho" method, and does not do anything else, you are running the risk that the garbage collector never runs. So the finalizer can't do its job. It is then up to you to call GC.Collect() yourself. You'd consider doing so every, say, 1000 threads you start. Or use ThreadPool.QueueUserWorkItem() or Task.Run() so you recycle the threads, the logical approach.
Use Perfmon.exe to verify that the GC indeed doesn't run. Add the .NET CLR Memory > # Gen 0 Collections counter for your program.
Try adding GC.WaitForPendingFinalizers(); after your call to GC.Collect(); I think that will get you what you are after. Complete source below:
EDIT
Also take a look at this from 2005: https://bytes.com/topic/net/answers/106014-net-1-1-possibly-1-0-also-threads-leaking-event-handles-bug. Almost the exact same code as yours.
using System;
using System.Threading;
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 1000000; i++)
{
Thread CE = new Thread(SendCEcho);
CE.Priority = ThreadPriority.Normal;
CE.IsBackground = true;
CE.Start();
Thread.Sleep(500);
CE = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
public static void SendCEcho()
{
int Counter = 0;
for (int i = 0; i < 5; i++ )
{
Counter++;
Thread.Sleep(25);
}
}
}

Threading Synchronizing

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadDemo
{
class Program
{
static public List<int> temp = new List<int >();
static public List<Thread> worker = new List<Thread>();
static public List<List<int>> Temporary = new List<List<int>>();
static void Main(string[] args)
{
temp.add(20);
temp.add(10);
temp.add(5);
foreach (int k in temp)
{
int z = 0;
worker[z] = new Thread(() => { sample(k); });
worker[z].Name = "Worker" + z.ToString();
worker[z].Start();
z++;
}
}
public static void sample(int n)
{
List<int> local = new List<int>();
for (int i = 0; i < n; i++)
{
local.Add(i);
}
Temporary.Add(local);
}
}
}
in this program i have the problem in thread when start the foreach loop in main program creates the three thread and also starts that thread.In that first thread operation is longer than other so it will take some time but other thread completed before the first
due to this order in temporary is changed .i need temporary list order as same as temp list order.how can achieve this using thread
There are three problems. First, variable capture:
foreach (int k in temp)
{
int z = 0;
worker[z] = new Thread(() => { sample(k); });
...
}
That's capturing the variable k in the lambda expression, not the value of k. The solution is to take a copy:
foreach (int k in temp)
{
int z = 0;
int copy = k;
worker[z] = new Thread(() => { sample(copy); });
...
}
See Eric Lippert's blog post for more information.
Secondly, you're always populating worker[0] because z will always be 0. If you want to populate other elements, you'll need to declare z outside. Alternatively, you could just add to the list.
Thirdly, there's the problem of not knowing the ordering of the results. The easiest way of fixing this is actually to turn Temporary into an array. Again, capture a copy of the variable to keep the right position. As ArsenMkrt says, you'll also need to update a list, which will involve locking.
Are you using .NET 4.0 (or could you)? Parallel Extensions makes all of this much, much simpler.
Here is a quick stab at your code:
class Program
{
static public List<int> temp = new List<int >();
static public List<Thread> worker = new List<Thread>();
static public List<List<int>> temporary = new List<List<int>>();
static public object sync = new object();
static void Main(string[] args)
{
temp.add(20);
temp.add(10);
temp.add(5);
// Add a corresponding number of lists
for( int i = 0; i < temp.Count; ++i)
{
temporary.Add(new List<int>);
}
// As Jon Skeet mentioned, z must be declared outside the for loop
int z = 0;
foreach (int k in temp)
{
// As Jon Skeet mentioned, you need to capture the value of k
int copy = k;
Thread t = new Thread(() => { Sample(copy, z); });
t.Name = "Worker" + z.ToString();
// set the thread to background, so your thread is
// properly closed when your application closes.
t.IsBackground = true;
t.Start();
// Calling worker[z] will always going to be out of bounds
// because you didn't add anything to to the worker list,
// therefore you just need to add the thread to the worker
// list. Note that you're not doing anything with the worker
// list, so you might as well not have it at all.
worker.Add(t);
z++;
}
}
// Supply the order of your array
public static void Sample(int n, int order)
{
for (int i = 0; i < n; i++)
{
// Technically in this particular case you don't need to
// synchronize, but it doesn't hurt to know how to do it.
lock(sync)
{
temporary[order].Add(i);
}
}
}
Now the temporary list should contain the other lists in the correct order (same as your tmp order). Your title does mention scheduling, but I'm not sure why you need scheduling here or what exactly you're trying to learn about scheduling.
At first, all your threads are access Temporary collection, and because List is not thread safe you should synch your threads to work correctly, and the second, You have no guaranty that the first thread will finish first if the first starts first, it depends how core will schedule threads.
To achieve what you want you can use thread synchronization mechanisms
If you need the threads' results in order, you should probably either pass them your z somehow, or have them return a result and join each of the threads in order in the main thread.
Other than that, you may be kinda screwed. Threads are, by their nature, prone to run at exactly the wrong time no matter what you need to do. You can't rely on them to start or stop exactly when you please; if you could, whole classes of concurrency issues would just go away.
I'd recommend you use threads sparingly. On single-core, single-CPU machines, your threading example would run slower than a decently coded solution without threading, because there's overhead involved in starting a thread. The only time i've ever seen threads be really useful, are times when you'd actually need to be appearing to do two things at once. Like keeping your UI working while you wait for input or do some arbitrarily big job in the background. Having threads for the sake of having them will end up driving you crazy.

Categories

Resources