I am trying Mono/.Net 3.5 under Linux (Ubuntu). I tried to use threads in Mono, but it doesn't seem to work properly.
public static void Main (string[] args)
{
Thread thread =new Thread(()=> fn("first"));
Thread thread1=new Thread(()=> fn("second"));
thread.Start();
thread1.Start();
}
static void fn(string name)
{
for(int i=0;i<10;i++)
Console.WriteLine(i+" "+name);
}
Both loops run sequentially, as if I am not using threads.
What is wrong?
Running this on Windows, most of the time all the first thread's writes happen before the second thread's.
The loop is too trivial to really see the effects of multiple threads running concurrently. The first thread may simply finish before the second starts.
Try putting a Sleep or spin loop in the main loop.
for(int i=0; i<10; i++) {
Console.WriteLine(i+" "+name);
Thread.Sleep(10);
}
or
for(int i=0; i<10; i++) {
Console.WriteLine(i+" "+name);
for(int j=0; j<100000; j++);
}
Related
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);
}
}
}
In the below program why the t.join functionality is not working. It will continue to type character O on the screen even when i have specified it to wait for the another thread to complete.
class Program
{
bool done;
static void Main(string[] args)
{
Thread t = new Thread(() => Go('U'));
for (int i = 0; i < 1000; i++)
{
Console.Write('O');
Thread.Sleep(500);
}
t.Start();
t.Join();
Console.WriteLine("Thread t has ended!");
Console.Read();
}
static void Go(char p)
{
for (int i = 0; i < 1000; i++)
{
Console.Write(p);
Thread.Sleep(500);
}
}
}
You never started the second thread - you're printing out Os, but you only start the second thread after you're done with that (in about eight minutes).
Move the t.Start(); before the loop, and it should work the way you expect it to work.
Don't guess around with multi-threading - it's incredibly easy to get subtly wrong. Learn what a thread is, what does Join do, and how to use multiple threads safely. Otherwise, you'll have a lot of fun debugging issues that are near impossible to reproduce and fix :)
I have a parallel algorithm which I have some barrier issues with. Before y'all scream "search" I can say I have looked at available posts and links, and I have followed the instructions for a barrier with Monitor.Wait and Monitor.PulseAll, but my issue is that all threads except the last one created (and initiated) is reached by the PulseAll from my main thread. Here are how the basic layout of the code is:
public static object signal = new object(); //This one is located as class variable, not in the method
public void RunAlgorithm(List<City> cities){
List<Thread> localThreads = new List<Thread>();
object[] temp = //some parameters here
for(int i = 0; i < numOfCitiesToCheck; i++){
Thread newThread = new Thread((o) => DoWork(o as object[]));
newThread.IsBackground = true;
newThread.Priority = ThreadPriority.AboveNormal;
newThread.Start(temp as object);
localThreads.Add(newThread);
}
//All threads initiated, now we pulse all
lock(signal){
Monitor.PulseAll(signal);
}
int counter = 0;
while(true){
if(counter == localThreads.Count){ break; }
localThreads[counter].Join();
counter++;
}
}
That's what done by the main thread (removed a few uneccessary pieces) and as stated before the main thread will always get stuck in the Join() on the last thread in the list.
This is how the method of the threads look like:
private void DoWork(object[] arguments){
lock(signal){
Monitor.Wait(signal);
}
GoDoWork(arguments);
}
Are there any other barriers I can use for this type of signaling? All I want is to let the main thread signal all threads at the same time so that they start at the same time. I want them to start at the same time inorder to have as close parallel as possible (I measure running time for the algorithm and a few other things). Is there any part of my barrier or code that is flawed (with the barrier I mean)? I tried running an instance with fewer threads and it still get stuck on the last one, I don't know why it is. I have confirmed by via VS debug that the last thread is sleeping (all other threads are !isAlive, while the last one isAlive = true).
Any help appreciated!
I managed to solve it using the Barrier class. Many thanks to Damien_The_Unbeliever! Still can't believe I haven't heard of it before.
public Barrier barrier = new barrier(1);
public void RunAlgorithm(List<City> cities){
List<Thread> localThreads = new List<Thread>();
object[] temp = //some parameters here
for(int i = 0; i < numOfCitiesToCheck; i++){
barrier.AddParticipant();
Thread newThread = new Thread((o) => DoWork(o as object[]));
newThread.IsBackground = true;
newThread.Priority = ThreadPriority.AboveNormal;
newThread.Start(temp as object);
localThreads.Add(newThread);
}
barrier.SignalAndWait();
int counter = 0;
while(true){
if(counter == localThreads.Count){ break; }
localThreads[counter].Join();
counter++;
}
}
private void DoWork(object[] arguments){
barrier.SignalAndWait();
GoDoWork(arguments);
}
I'm trying to run a clock on the console application of C#. It should be pretty straight forward s=using threads and stopwatch, but somehow i cant start the thread.. here's the code:
public static void showBoard()
{
for(int i = 0 ; i< 40 ; i++)
{
for (int j = 0 ;j<40 ; j++)
{
Console.Write(board[i, j]);
}
Console.Write('\n');
}
Thread t = new Thread(Timer);
}
public static void Timer()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (true)
{
Console.SetCursorPosition(45, 1);
Console.Write(stopwatch.Elapsed.ToString());
}
}
Function Timer dont even start the excution, kindly tell me what am i doing wrong.
you forgot something
t.Start();
Threads need to be started explicitly, otherwise they don't run.
You need to start it with
t.Start();
see http://msdn.microsoft.com/en-us/library/a9fyxz7d(v=vs.110).aspx
You need to explicitly start a thread.
Use t.Start() ;
or
Do this
Thread t = new Thread(Timer).Start() ;
Check the following links if you need further info:-
http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx
http://www.codeproject.com/Articles/6678/Introduction-to-Threads-in-C
http://www.albahari.info/threading/threading.pdf
You need to add...
t.Start
...to start your thread.
You have created object of thread class, and now you have to start the thread, which you can do use the Start() method.
Thread t = new Thread(Timer);
t.Start();
static int i = 0;
static void Main()
{
ThreadTest tt = new ThreadTest();
new Thread(tt.Incr).Start();
tt.I();
tt.I2();
}
void Incr()
{
for(int x = 0; x < 3; x++)
{
Console.WriteLine(i);
i++;
}
}
void I()
{
while(i <= 3)
{
if(i==3)
break;
Console.WriteLine("Value of i in I:{0}",i);
}
}
void I2()
{
Console.WriteLine("\t\tFinally i is:{0}\n\n",i);
}
I have run this piece of code about a few hundred times now and find that I2 always executes last. Why does this happen? May be a few hundred times is not enough to see the true unpredictability of threads?
Output of 11 runs
Well, I2() is the last method in Main() and it is not threaded in any way.
So what's the question, why the thread finishes earlier?
That's because I2() is run after I() and the while-loop in I() effectively waits for the thread to finish first.
The method I2 will always be executed last. This has nothing to do with threads.
static void Main()
{
ThreadTest tt = new ThreadTest();
new Thread(tt.Incr).Start();
tt.I(); // This will be executed first
tt.I2(); // This will be executed last
}
The flow of the newly started thread and the current thread is not synchronized, but the current thread will continiue its operation in a synchronous fashion executing statements in the order as the appear. In this case I() will be called before I2().