www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - D threading and shared variables

reply Archie Allison <archie_allison compuserve.com> writes:
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
next sibling parent reply Doc Andrew <x x.com> writes:
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
parent reply Archie Allison <archie_allison compuserve.com> writes:
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
next sibling parent reply Mike Wey <mike-wey example.com> writes:
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
parent Archie Allison <archie_allison compuserve.com> writes:
On Sunday, 7 April 2019 at 17:52:40 UTC, Mike Wey wrote:
 
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.
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(); } } } } };
Apr 07 2019
prev sibling parent Kagamin <spam here.lot> writes:
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
prev sibling parent reply Johan Engelen <j j.nl> writes:
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
parent reply Archie Allison <archie_allison compuserve.com> writes:
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:
 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
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.
Apr 09 2019
parent Kagamin <spam here.lot> writes:
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