Wednesday, June 28, 2006

Multi-Thread Synchronization vs. Real-Time

When dealing with multi-threading, some of ue are confused by real-time and thread synchronization. Sometimes we are not sure about which we need in our applications.

By real-time, I mean that the simulation time your program completes should go hand-in-hand with your wall clock, no faster nor slower. Let's say you're simulating the traffic on a highway. If you want to simulate traffic for a period of one second, then your program should complete that one-second simulation within one second time. Only this way you can acheive real-time. Multiple CPUs can help to acheive real-time through better parallelism. But if the computation is very simple, one CPU can do the job too. As you may notice now, parallelism is not a necessity in pursuing real-time, as lon as you can catch up the wall clock.

Synchroniztion is a different issue. It is about the collaboration between two threads. It has nothing to do with how fast or slow your CPU is. You don't need multiple or faster CPUs to acheive synchronization. One of the major purposes for synchronization is protecting resources shared by more than one thread.

Tuesday, June 20, 2006

On Windows, Why Should I Use _beginthreadex Instead of CreateThread/Ex to Create Threads?

In genral, using CreateThread is not thread safe. It is not because CreateThread/Ex is not thread safe itself, but because using it in applications linked with a CRT (C/C++ Run-Time) library is not. Two noticeable items:

1) The applications built on VC++ 6, regardless of type, have been linked to one of the CRT libraries shiped with VC++:

Single-Threaded (default)
Multithreaded DLL
Debug Single-Threaded
Debug Multithreaded
Debug Multithreaded DLL

You could avoid calling CRT functions in your module, but you have no control over who, where and when CRT is used in the application.

2) For multithreaded C/C++ to work properly, a data structure must be created and associated with each thread that uses CRT functions. CreateThread is an OS call, but _beginthreaded is a CRT call. If you call CreateThread, OS doesn't know:
- your application is written in C/C++,
- you are calling functions that aren't natively thread-safe
- it needs to allocate a CRT data block for the new thread
When you call _beginthreaded, CRT knows and handles all these in a proper manner. Then, CRT calls CreateThread inside _beginthreaded to actually create the thread you wanted.

Jeffery Richter's classic text "Programming Applications for Microsoft Windows" (4th Ed.) Chapter 6 has explained this in more detail.

.NET FAQ: How to Shutdown My Computer Programatically in C#?

Use .NET Process class. Make this call to its Start method:
System.Diagnostic.Process.Start("shutdown.exe", "-s -f -t 00");
For more info on how to use .NET Process class, check this out: click here.

Get This Blog Organised A Bit...

I found some time to get this blog organised into categories. Currently, I only opened two specific categories: .NET FAQ and ToolBox, since most my posts so far are in the twoe areas.

I'd like to hear what you guys think and how I can improve the blog.

Monday, June 19, 2006

.NET FAQ: Can A Button-Click Event on One Window Be Handled by Another?

Well, while this is entirely possible, you should avoid doing so. There are good reasons for this recommendation. Tow important ones are:
1) The button-click events are handled through .NET event model, in which when an event occurs, the associated delegate will be called. The delegate is a private member function of the form class. Letting another form to handle this event will break the protection of the delegate function.
2) When the delegate is called, the sender object is passed as an input parameter. In this case, it is the button that has been clicked. Again, the button object usually is a private data member of the form class. Letting another form to handle this event will inevitably expose the button object to tat foreign form.

Are there other ways that the button click on one window (Form A) can be handled by another (Form B)? Yes. Within the event handler, Form A can call into Form B in any proper way you want. For example, in the event handler, you may define a button-type (or click-type) parameter and pass it to the callback function of Form B. Then, Form B can take different actions based on the button parameter from Form A.

Monday, June 05, 2006

.NET FAQ: Is Observer Pattern a Better Alternative to Event Model for GUI?

Observer pattern probably is one of the most often used design patterns originally recommended by "The Gang of Four". In many cases, the Observer model can work as a GUI notification mechanism, but it is less than ideal. Just like any other patterns, Observer has numerous limitations, particularly when it is used on GUI. Some important limitations are:

1) As with any interface-based design, your oberver model is an very intrusive and very public solution. Suppose you wanted to subscribe to many notifications, not one. This is typically what you do with GUI. A typical GUI generates a large number of events to which you might need to subscribe.

2) Another related problem is that use of an interface means that your Update() method must be public. Any code then can call it at any time.

3) That said, Observer has to be interface-based. Because if you don't use interface-based design, SubjectBase class would be tightly coupled to GUIObservser class. In other word, only GUIObserver instances can attach to a Subject. If some other class has a method that you want Notify() to call, you'll have to create a whole new SubjectBase-like class. So the problem is not in the interface; it is Observer model's limitation.

4) Observer model handles one-to-many subscription fairly well. By one-to-many, I mean that many observers subscribe to one subject. But when an event fires, the notifications to all the subscribed observers are linear, meaning that observers will get callback one by one following exactly the same order for every loop. There are variants that instead of direct callbacks, Subject puts a message on each observer's message queue. This way, they create a "random" notification mechanism.

5) Thread-safety issue. There usually is very tight coupling between Subject and Observers. when notifying, Subject has to call into Observers' update() one by one. If one call has not returned promptly, or caught some exception, next call cannot be made. To avoid this, some usually implements a multithreaded refresh mechanism on the Subject side. So now the thread-safety becomes an issue, as the observer's data has to be proteced while it's being updated.

6) .NET Delegate/Event model solves some of these problems and creates a safer, more robust, more encapsulated style of notification. Specifically, I think it solves the problems 1-3 cleanly. I'm not quite sure whether the event model is thread safe by itself, though.

On Windows, I think the original messaging model and now the new event model is an better option than primitive Observer model. I still use Observer patterns a lot, but not for replacing Windows event model. On non-Windows platforms, I do see numerous examples of using Observer pattern as a GUI notification mechanism (I guess, Unix/Linux platform does not have a built-in messaging framework like Windows). I am pretty sure that many developers out there use Observer pattern on many other areas as well.