Page 1 of 1

threads and console [solved]

Posted: Tue Nov 13, 2007 12:39 pm
by Kukulkan
Hi,

I try to do some calculations in seperate threads. Each thread writes some status and other information using PrintN() to the console window.

Now, at high performance, the output is getting scrambled as some threads seem to write to the console at the same moment.

Is there any idea how to prevent this?

Kukulkan

Re: threads and console

Posted: Tue Nov 13, 2007 12:44 pm
by PB
Is thread safety enabled in the compiler options?

Posted: Tue Nov 13, 2007 12:52 pm
by srod
Are you using a Mutex object to ensure that only one thread writes to the console at a time?

Posted: Tue Nov 13, 2007 1:59 pm
by Kukulkan
Hi,
Is thread safety enabled in the compiler options?
Yes.
Are you using a Mutex object to ensure that only one thread writes to the console at a time?
Aaaahhhh. I read the help for this function and this is exactly what I needed. Thank you!

Kukulkan

Posted: Tue Nov 13, 2007 2:23 pm
by Fred
May be we should automatically mutex protect the Print(N)() commands in threaded mode then.

Posted: Tue Nov 13, 2007 2:38 pm
by srod
Fred wrote:May be we should automatically mutex protect the Print(N)() commands in threaded mode then.
That's not a bad idea Fred. :)

Posted: Tue Nov 13, 2007 2:39 pm
by Kukulkan
Hi Fred,
May be we should automatically mutex protect the Print(N)() commands in threaded mode then.
In my case, I learned a bit more about programing threads in this way. :wink:

But yes, this may be a good idea because no one likes to scramble console output.

Kukulkan

Posted: Tue Nov 13, 2007 2:49 pm
by srod
Mind you Fred, if you're going to go this far, one might ask why not, for example, Mutex protect linked lists in Threaded mode etc.

I reckon you'll either have to mutex protect a whole bunch of things, or leave it as it is. Instead, have the help manual upgraded a little to discuss the where's and wherefore's of threadsafe applications etc. Point out that linked lists are not inherently threadsafe etc. and that a mutex should be considered by the developer.

I think personally I would prefer it left as it is for performance reasons.

For example, I might write a threaded console application but in which a mutex is not required because only the main thread writes to the standard output etc.

Posted: Tue Nov 13, 2007 3:05 pm
by Fred
theorically, all single commands should work as expected in threadmode, which is not the case with this one, that's why i wondered. About linkedlist, every single commands shouldn't be a problem in threaded mode, but using them in sequence is wrong and can't be really protected.

Posted: Tue Nov 13, 2007 3:14 pm
by srod
Fred wrote:theorically, all single commands should work as expected in threadmode, which is not the case with this one, that's why i wondered. About linkedlist, every single commands shouldn't be a problem in threaded mode, but using them in sequence is wrong and can't be really protected.
Yes, good point - single commands! :)

The developer has no choice but to assume responsibility for protecting linked lists in threaded environments then because it's only when multiple commands are strung together that threadsafety becomes a problem. Yes, I see. The compiler would need some pretty dandy 'heuristics' to cope with this! :)

With this in mind, it perhaps does indeed make sense to protect PrintN() etc.

Posted: Tue Nov 13, 2007 6:58 pm
by freak
Fred wrote:theorically, all single commands should work as expected in threadmode, which is not the case with this one, that's why i wondered. About linkedlist, every single commands shouldn't be a problem in threaded mode, but using them in sequence is wrong and can't be really protected.
This is not true. All single command work as long as they do not access a shared
resource.

The only exception here is the access to global floats, longs, words, bytes. (NOT quads and doubles!),
as the access to them is atomic, meaning you can never end up with a
"half-written long value", no matter where the thread execution gets
switched.

A linkedlist (if not protected) is such a shared resource. Modifying the list (AddElement, DeleteElement)
involves changing pointers inside the list, which means there is the possibility
of a race-condition if two threads execute such a command at the same time.
(even if there is no sequence of commands)

(Example: ThreadA reads the Lists *NextElement pointer to execute an AddElement().
Then the thread execution is switched to ThreadB which changes this pointer
by fully executing an AddElement()/DeleteElement().
Now the system switches back to ThreadA who now tries to manipulate the
List with the invalid *NextElement pointer it read before... boom.)

So LinkedList access to a List shared between threads ALWAYS needs a mutex
protection to be save.
Implementing this in the library itself would be too much of a performance hit.


So the rule for the PB commandset is:
With threadsave mode on all the commands are threadsafe as long as they are used
on resources local to the thread. As soon as something shared is used,
there needs to be a protection.
(except for some simpler commands, but its generally better to protect everything)

(Example: ResizeImage() on two images in two threads: no problem.
ResizeImage() on the same image in two threads at once... boom)

The reason there is simple: Every more complex PB command is implemented
as a sequence of actions which, interrupted at the wrong time by another access to the shared resoruce could be problematic.
This is a general problem of thread programming and cannot be solved by
simply mutex protecting every command. This would kill performance and make thread useless
(as the final execution is sequential again as each thread waits for the other)

For the PrintN():
I think the console API is threadsafe (protected by an internal mutex i guess),
but i cannot find any official documentation from MS on this, only rumors
in discussions over the internet.

If this is the case, then we can make the PrintN() threadsafe even without
the need for an additional mutex protection. We just need to change the
command to print everything in a single call (so far it prints the newline separately)

I will research this and see what can be done.

Posted: Tue Nov 13, 2007 7:04 pm
by srod
A linkedlist (if not protected) is such a shared resource. Modifying the list (AddElement, DeleteElement)
involves changing pointers inside the list, which means there is the possibility
of a race-condition if two threads execute such a command at the same time.
(even if there is no sequence of commands)
Ah yes, a single PB command <> a single instruction! :)

I think the performance hit issue is the all important one which is why I'm happy for things to stay the way they are!