Live data from Hacker News

Multithreaded toolkits: A failed dream? (2004)

weblogs.java.net

31–40 of 64 posts

Re: Multithreaded toolkits: A failed dream? (2004)

#31

Well, its also a poorly motivated dream unless you have a sexual fetish for the Java style of abstraction where everything is completely independent. Who the heck wants multi-threaded GUIs? User interaction proceeds sequentially, so most objects don't require locks. The rare exceptions in my software is rendering or IO on a separate thread, and these don't nicely fit abstraction models, as mentioned in other posts th…

> Who the heck wants multi-threaded GUIs? Widgets aren't static; presumably you want them to keep updating (spinners, size changes, status updates) when the user is interacting with other elements.

Modern single-threaded UI frameworks don't go into a loop while you're interacting with something. Say you click on a button and drag. This enters the UI framework as a "mouse down" event followed by several "mouse dragged" events. After handling each event (or between events), the framework can decide to do other work, like updating a spinner.

Re: Multithreaded toolkits: A failed dream? (2004)

#32

Well, its also a poorly motivated dream unless you have a sexual fetish for the Java style of abstraction where everything is completely independent. Who the heck wants multi-threaded GUIs? User interaction proceeds sequentially, so most objects don't require locks. The rare exceptions in my software is rendering or IO on a separate thread, and these don't nicely fit abstraction models, as mentioned in other posts th…

> Who the heck wants multi-threaded GUIs? Widgets aren't static; presumably you want them to keep updating (spinners, size changes, status updates) when the user is interacting with other elements.

[deleted]

Re: Multithreaded toolkits: A failed dream? (2004)

#33
post #20

Earlier quoted context omitted.

Locks turn out to be unnecessary for multithreaded code. A ringbuffer of messages is only slightly more complex, yet the gains are massive. Both in performance and simplicity. It's possible to manage a ringbuffer without any locks. The trick is to have a counter for the producer thread, and a counter for each consumer thread. Whenever the producer wants to know "Is it safe to add a message?" it takes the minimum of a…

I would like to read more about what you described here. Know of any good articles or open source projects where this is done?

There are multiple ways to make a lock-free ringbuffer; most use some sort of similar trick with per-consumer atomic counters, though I hadn't heard of something as simple as the minimum-modulo trick described in the gp! Some implementations:

http://mechanitis.blogspot.com/2011/07/dissecting-disruptor-...

http://www.boost.org/doc/libs/1_59_0/doc/html/boost/lockfree... - hard to find implementation details though

http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-... (uses per-producer counters instead, and relaxes some ordering guarantees; see comments)

Re: Multithreaded toolkits: A failed dream? (2004)

#34

Earlier quoted context omitted.

Rust prevents races but not deadlocks, which is one of the bigger problems in multithreaded GUI code.

Locks turn out to be unnecessary for multithreaded code. A ringbuffer of messages is only slightly more complex, yet the gains are massive. Both in performance and simplicity. It's possible to manage a ringbuffer without any locks. The trick is to have a counter for the producer thread, and a counter for each consumer thread. Whenever the producer wants to know "Is it safe to add a message?" it takes the minimum of a…

Ringbuffers (or any queue, actually) don't solve the problems associated with locks. Often when people talk about locks when discussing concurrent algorithms, they don't necessarily mean the particular construct called a lock but any synchronization mechanism that might end up suspending some computation when waiting for another to happen, so a queue may well be a lock in this kind of discussion.

To see the duality between locks and queues note that any queue can be implemented with any list/array and a lock, and a lock itself is nothing more than some atomic operation, plus a queue plus a mechanism to suspend computation. Whether that suspension involves an actual parking of the kernel thread or spinning, is an implementation detail from the perspective of the algorithm.

You can use queues without deadlocks, but then you won't have the same advantages locks can give you (transactions), or you can have the same advantages, but then get the same problems.

Re: Multithreaded toolkits: A failed dream? (2004)

#35
post #31

Earlier quoted context omitted.

> Who the heck wants multi-threaded GUIs? Widgets aren't static; presumably you want them to keep updating (spinners, size changes, status updates) when the user is interacting with other elements.

Modern single-threaded UI frameworks don't go into a loop while you're interacting with something. Say you click on a button and drag. This enters the UI framework as a "mouse down" event followed by several "mouse dragged" events. After handling each event (or between events), the framework can decide to do other work, like updating a spinner.

That's not a "modern" GUI framework approach - eventloops have been a feature of GUI systems back to the Apple Lisa and Windows 1.

Re: Multithreaded toolkits: A failed dream? (2004)

#36
post #7

A big reason why multithreaded UI doesn't work is that the platform code (win32, cocoa) generally has poor support for interacting with OS objects from multiple threads. For instance, NSView instances can only be operated on from the main thread ( https://developer.apple.com/library/mac/documentation/Cocoa/... ). Handling OpenGL context access from multiple threads is terrible, too. I'm quite excited about the additi…

> For instance, NSView instances can only be operated on from the main thread Cocoa is the toolkit, not the OS, so this is just Cocoa taking exactly the approach described in the fine article.

It's also an unavoidable part of writing graphical code on OS X, so, for all intents and purposes, it is the OS.

Re: Multithreaded toolkits: A failed dream? (2004)

#37
post #31

Earlier quoted context omitted.

Modern single-threaded UI frameworks don't go into a loop while you're interacting with something. Say you click on a button and drag. This enters the UI framework as a "mouse down" event followed by several "mouse dragged" events. After handling each event (or between events), the framework can decide to do other work, like updating a spinner.

That's not a "modern" GUI framework approach - eventloops have been a feature of GUI systems back to the Apple Lisa and Windows 1.

Yes, event loops are quite an old idea. I just put "modern" there to exclude old systems that encouraged polling. For example, I'm pretty sure classic Mac OS entered a loop while tracking the mouse in menus.

Re: Multithreaded toolkits: A failed dream? (2004)

#38

Well, its also a poorly motivated dream unless you have a sexual fetish for the Java style of abstraction where everything is completely independent. Who the heck wants multi-threaded GUIs? User interaction proceeds sequentially, so most objects don't require locks. The rare exceptions in my software is rendering or IO on a separate thread, and these don't nicely fit abstraction models, as mentioned in other posts th…

Anyone who has seen the responsiveness of e.g. AmigaOS under heavy load next to many modern systems might be inclined to want (more) multi-threaded GUIs.

Heavy use of multi-threading to disconnect GUI updates from the actual work was essential to making that happen.

AmigaOS sacrificed throughput over responsiveness all over the place (e.g. something as trivial as cut and paste from a terminal would easily involve half a dozen threads with message passing).

You don't need separate threads for every little component, though.

Re: Multithreaded toolkits: A failed dream? (2004)

#39
post #22
post #14

Earlier quoted context omitted.

You don't need a multi-threaded GUI for that. You can have the GUI running on one thread while the task runs on another.

Sure. You put a message queue in there and create command objects for all the updates that tasks might want to make to the UI. It's not hard; in fact it's thoroughly mechanical, so it's exceedingly tedious to program. So why isn't the computer doing it for me? I'd happily sacrifice some performance if I could just write the change I wanted to make in the thread where I wanted to make it, and have the computer take ca…

Just have the ability to send closures (std::function) to other threads' message queues. Then you can use inline lambda syntax.

Re: Multithreaded toolkits: A failed dream? (2004)

#40
post #38

Well, its also a poorly motivated dream unless you have a sexual fetish for the Java style of abstraction where everything is completely independent. Who the heck wants multi-threaded GUIs? User interaction proceeds sequentially, so most objects don't require locks. The rare exceptions in my software is rendering or IO on a separate thread, and these don't nicely fit abstraction models, as mentioned in other posts th…

Anyone who has seen the responsiveness of e.g. AmigaOS under heavy load next to many modern systems might be inclined to want (more) multi-threaded GUIs. Heavy use of multi-threading to disconnect GUI updates from the actual work was essential to making that happen. AmigaOS sacrificed throughput over responsiveness all over the place (e.g. something as trivial as cut and paste from a terminal would easily involve hal…

Was the UI really heavily multithreaded compared to today's systems? I thought there was a lot of events and message-passing going on in AmigaDOS much like in current GUI systems.
Post reply on HN