Which implications does multithreading have on the architecture of a desktop application?
Asked Answered
C

1

7

I am writing a multithreaded desktop application.

Generally

I am unsure about the implications that multitreading has on the architecture. There is a lot of literature on architecture, but I know none that takes multithreading into account. There is a lot of literature on the low level stuff of multithreading (mutexes, semaphores, etc.) but I know none that describes how these concepts are embedded into an architecture.

Which literature do you recommend to fill this gap?

Particularly

My application consist of

  • Presentation that creates and manages dialogs using a GUI toolkit,
  • Kernel that knows all about the domain of the application,
  • Controller that knows the Kernel and the Presentation and moderates between these two.

To be more precise, here is how files are opened:

  1. The Presentation signals a FileOpenCommand.
  2. The ApplicationController recieves this signal and
    1. uses the ApplicationKernel to create a File object,
    2. uses the ApplicationPresentation to create a FilePresentation object,
    3. creates a FileController object, passing the File and the FilePresentation to the constructor.
  3. The FileController registers itself as an observer on its File and FilePresentation.

Let's say File provides a long running operation Init() that should not block the user interface. There are two approaches that came to my mind:

  1. File::Init() returns an object that encapsulates a thread and can be used to register an observer that is notified about progress, errors, completion etc. This puts a lot of responsibility into the FileController (who would be the observer), because it is now accessed from both the main thread as well as from the working thread.
  2. Hide the working thread completely from the Controller. File::Init() would return nothing, but the ApplicationKernel would signal creation, progress and errors of long running operations in the main thread. This would drag a lot of communication though the ApplicationKernel, turning it into something like a god object.

Which of these two is the common approach to multithreading in a desktop application (if any)? Which alternative approaches do you recommend?

Cryotherapy answered 28/12, 2010 at 16:20 Comment(1)
Since you started a bounty for this question, you seem unsatisfied with the given answer. You have not however edited your question to clarify, what information you want which is not given in the answer. It would help other users in answering your question in order to earn the bounty.Bacteriostasis
S
3

I suggest that you consider using the actor model. It is a concurrency abstraction that hides a lot of the details associated with threads, locks, etc.

Edit

Some additional comments spurred by @CMR's comment...

Under an actor model, I imagine that the application would still be structured using the same components as suggested in the question: Presentation, ApplicationController, etc. The difference with the actor model is that the components (now actors) would not hold direct references to each other. Rather, they would hold channels to which they could post asynchronous, immutable, messages to one another.

The sequence of events in the "open a file" case would be essentially the same in the actor model, except that channels would be passed to the FileController in step 2.3 instead of direct object references. Similarly, observer registration in occurs through channels.

So what's the difference? The main difference is that none of the code needs to be thread-aware. Threads are invisible to the application logic, being the concern of the actor framework. If one can follow the discipline of only passing immutable objects through the channels (which some actor frameworks enforce), then virtually all the difficult logic associated with thread synchronization disappears. Of course, one has to switch mindsets from a synchronous programming model to an asynchronous one -- not necessarily a trivial task. However, it is my opinion that the cost of that switch is outweighed by the benefit of not having to think about thread-safety (at least in systems of some complexity).

In UI programming in particular, asynchronous models make it much easier to give nice user feedback. For example, a UI element may kick off a long-running task, display a "working..." message, and then go to sleep. Some time later, a message arrives delivering the results of the long running task which the UI element then displays in place of the "working..." message. In similar fashion, tree views can be built incrementally as each tree node's data arrives in an incoming message.

You can think of an actor model as a generalization of the classic UI "event pump" approach -- except that every component (actor) is running its own event pump simultaneously instead of one pump dispatching to a bunch of components. Actor frameworks provide a way to run large or even huge numbers of such "simultaneous pumps" with very low overhead. In particular, a small number of threads (say, one per cpu) service a large number of actors.

Standoff answered 28/12, 2010 at 16:46 Comment(3)
On first glance, the actor model seems like a possibility to reduce the complexity associated with managing threads. I have to dig deeper into it. Thanks.Cryotherapy
If Oswald models FileController as a messaging system: File::init() would register itself with a common FileController with a filter, and return the filter. Messages are directed from the FilePresentation to File only using the filter, would that be an actor model?Tumid
@Tumid All communication between actors in an actor model is asynchronous, through message queues. If by filter you mean the channel through which messages are sent to the messaging system, then I think we are talking about the same thing. An actor in itself is very lightweight (roughly coroutine-sized), while the whole actor framework is a kind of "messaging system". I'm not sure from your example whether the messaging system you contemplate is analogous to a single actor, or to the whole actor framework.Standoff

© 2022 - 2024 — McMap. All rights reserved.