digitalmars.D.learn - D threading and shared variables
- Archie Allison (16/16) Apr 07 2019 I have written an industrial control program which uses serial
- Doc Andrew (9/25) Apr 07 2019 When you say it "rarely works" when run as a GUI app (vs
- Archie Allison (7/15) Apr 07 2019 The codebase is a reasonable size so too big (and proprietary) to
- Mike Wey (7/13) Apr 07 2019 How are you using the GUI, GTK is not thread safe, all gui function
- Archie Allison (48/53) Apr 07 2019 All GUI updates are sent from a worker thread to the GUI thread
- Kagamin (4/6) Apr 08 2019 You can reduce it to a minimal example that doesn't work. Static
- Johan Engelen (6/9) Apr 07 2019 Manually setting the entry point sounds problematic if no other
- Archie Allison (7/17) Apr 09 2019 I changed the main code as described in the article but the
- Kagamin (2/2) Apr 11 2019 Well, if the code is too complex to debug, the usual solution is
I have written an industrial control program which uses serial ports to communicate with hardware but am having problems, perhaps with shared memory, on Windows. The SerialPort class calls C object-file functions. Transmits are on one thread and receives on another (all within a class derived from Thread), with a signal(created from a mutex) notifying the transmit thread when a packet has arrived. This generally works OK when tied to a Console but when link options are changed to be SUBSYSTEM:WINDOWS and ENTRY:mainCRTStartup it rarely does. Compiling with -vtls shows the serial port is in thread local storage. As a hardware resource, I wasn't sure if this matters. I've tried casting to a shared object so it no longer appears in the -vtls list, with no difference. Does anyone have ideas about where I may have misunderstood the threading and shared-memory design of D or what I can look at?
Apr 07 2019
On Sunday, 7 April 2019 at 14:08:07 UTC, Archie Allison wrote:I have written an industrial control program which uses serial ports to communicate with hardware but am having problems, perhaps with shared memory, on Windows. The SerialPort class calls C object-file functions. Transmits are on one thread and receives on another (all within a class derived from Thread), with a signal(created from a mutex) notifying the transmit thread when a packet has arrived. This generally works OK when tied to a Console but when link options are changed to be SUBSYSTEM:WINDOWS and ENTRY:mainCRTStartup it rarely does. Compiling with -vtls shows the serial port is in thread local storage. As a hardware resource, I wasn't sure if this matters. I've tried casting to a shared object so it no longer appears in the -vtls list, with no difference. Does anyone have ideas about where I may have misunderstood the threading and shared-memory design of D or what I can look at?When you say it "rarely works" when run as a GUI app (vs console), it makes me think that there's probably a race condition going on, and the extra context switching that takes place in GUI mode makes it more likely. I haven't tried it in D, but you may be able use Application Verifier with your app to add checks for lock contention. Without more information about the way your threads are synchronized it's hard to say for sure though.
Apr 07 2019
On Sunday, 7 April 2019 at 14:35:24 UTC, Doc Andrew wrote:When you say it "rarely works" when run as a GUI app (vs console), it makes me think that there's probably a race condition going on, and the extra context switching that takes place in GUI mode makes it more likely. I haven't tried it in D, but you may be able use Application Verifier with your app to add checks for lock contention. Without more information about the way your threads are synchronized it's hard to say for sure though.The codebase is a reasonable size so too big (and proprietary) to share. It's always run with a GUI (GTKD), it's just the difference in linking so launching (a)GUI + attached console for stdout.writeln vs. (b)just the GUI window. There's nothing I'd expect to cause races or deadlocks.
Apr 07 2019
On 07-04-2019 16:49, Archie Allison wrote:The codebase is a reasonable size so too big (and proprietary) to share. It's always run with a GUI (GTKD), it's just the difference in linking so launching (a)GUI + attached console for stdout.writeln vs. (b)just the GUI window. There's nothing I'd expect to cause races or deadlocks.How are you using the GUI, GTK is not thread safe, all gui function calls should be made from the GUI thread. Last time i checked threadsEnter and threadsLeave didn't work properly on windows. -- Mike Wey
Apr 07 2019
On Sunday, 7 April 2019 at 17:52:40 UTC, Mike Wey wrote:All GUI updates are sent from a worker thread to the GUI thread using the D message passing system and immutable object arguments. I'm pretty satisfied it's not a problem. The general principle of the classes doing the comms are: class name :Thread { Mutex m; Condition sig; shared char[] shared_buffer; CommunicationClass comm; this() { m = new Mutex; sig = new Condition(m); comm = new CommunicationClass; super(&receive_thread); start(); } //the main routine being called void packet_transaction() { comm.send_data(); synchronized(m) { if (sig.wait(dur!("seconds")(1)) == true) do_something(); else do_timeout(); } } void receive_thread() { local_buffer; while(true) { local_buffer += comm.get_data(); if (some condition) { synchronized(m) { copy local_buffer to shared_buffer; sig.notify(); } } } } };How are you using the GUI, GTK is not thread safe, all gui function calls should be made from the GUI thread. Last time i checked threadsEnter and threadsLeave didn't work properly on windows.
Apr 07 2019
On Sunday, 7 April 2019 at 14:49:20 UTC, Archie Allison wrote:The codebase is a reasonable size so too big (and proprietary) to share.You can reduce it to a minimal example that doesn't work. Static variables are thread local by default in D unless they are marked as shared or __gshared.
Apr 08 2019
On Sunday, 7 April 2019 at 14:08:07 UTC, Archie Allison wrote:This generally works OK when tied to a Console but when link options are changed to be SUBSYSTEM:WINDOWS and ENTRY:mainCRTStartup it rarely does.Manually setting the entry point sounds problematic if no other precautions are taken. Are you sure that druntime is initialized? See [1]. - Johan [1] https://wiki.dlang.org/D_for_Win32
Apr 07 2019
On Sunday, 7 April 2019 at 22:18:56 UTC, Johan Engelen wrote:On Sunday, 7 April 2019 at 14:08:07 UTC, Archie Allison wrote:I changed the main code as described in the article but the effect seems to be the same as just using the link options. Is there anything obviously wrong with the variable declarations in the code sample? It looks like having a console output window in addition to just the GUI is having some sort of effect on threading, sharing or timing.This generally works OK when tied to a Console but when link options are changed to be SUBSYSTEM:WINDOWS and ENTRY:mainCRTStartup it rarely does.Manually setting the entry point sounds problematic if no other precautions are taken. Are you sure that druntime is initialized? See [1]. - Johan [1] https://wiki.dlang.org/D_for_Win32
Apr 09 2019
Well, if the code is too complex to debug, the usual solution is to try simpler code and see if it works.
Apr 11 2019