Re: Thread to watch keyboard during main's infinite loop

2020-05-06 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 7 May 2020 at 01:33:12 UTC, Daren Scot Wilson wrote:

   import core.thread: sleep;


It sould be

import core.thread : Thread;

Thread.sleep(1.secs); // or whatever

sleep is a static method on the Thread class.



Re: Thread to watch keyboard during main's infinite loop

2020-05-06 Thread Daren Scot Wilson via Digitalmars-d-learn

On Thursday, 7 May 2020 at 01:02:57 UTC, ag0aep6g wrote:


Thank you, this is 110% helpful.

Actually, I'd like to return the excess 10%.  My dmd compiler 
does not like:


   import core.thread: sleep;

so I put the code back the way I had, just to get on with work.


Use `shared` so that all threads use the same variables:

shared bool running=true;
shared char command = '?';



"shared" did the job.  I had read about "thread local" and 
"shared" in D before, but did not comprehend. Now I do :)




This sequence of events is entirely possible:

1) main: cmd = command
2) cmdwatcher: command = c
3) main: command = ' '

It won't happen often, but if it does, your input has no effect.


For this tool, lost key hits are not a problem.  At least, that's 
what I say for now. I may be back next week for help with that.  
For now, the trousered ape running the software will just have to 
tap the key again. (Or the key + Enter.)


Re: Thread to watch keyboard during main's infinite loop

2020-05-06 Thread ag0aep6g via Digitalmars-d-learn

On 07.05.20 02:13, Daren Scot Wilson wrote:

import std.stdio;
import core.stdc.stdio;  // for getchar().  There's nothing similar in D 
std libs?

import std.concurrency;
import core.thread; // just for sleep()


Instead of the comment you can write:

import core.thread: sleep;


bool running=true;
char command = '?';


These variables are thread-local by default. That means independent 
`running` and `command` variables are created for every thread. If you 
make changes in one thread, they won't be visible in another thread.


Use `shared` so that all threads use the same variables:

shared bool running=true;
shared char command = '?';


void cmdwatcher()
{
     writeln("Key Watcher");
     while (running)  {
     char c = cast(char)getchar();
     if (c>=' ')  {
     command = c;
     writefln(" key %c  %04X", c, c);
     }
     }
}

void main()
{
     writeln("Start main");
     spawn();

     while (running) {
     writeln("Repetitive work");
     Thread.sleep( dur!("msecs")( 900 ) );

     char cmd = command;  // local copy can't change during rest of 
this loop


For values that don't change, we've got `immutable`:

immutable char cmd = command;


     command = ' ';


Note that even when using `shared` you still have to think hard to avoid 
race conditions.


This sequence of events is entirely possible:

1) main: cmd = command
2) cmdwatcher: command = c
3) main: command = ' '

It won't happen often, but if it does, your input has no effect.


Thread to watch keyboard during main's infinite loop

2020-05-06 Thread Daren Scot Wilson via Digitalmars-d-learn
I'm writing a simple command line tool to send data by UDP once 
per second forever, to test some software on another machine.  
Not actually forever, of course, but until ^C or I hit 'Q'. I 
want to tap keys to make other things happen, like change the 
data or rate of sending.


Not sure of the best way to do this. Thought I'd try a thread 
whose job is just to loop, calling readln() or getch() or 
something similar, and setting a global variables according to 
what key was tapped.  The loop in the main thread can then break, 
or do some other action, according to the value of that variable.


Code I have written is below, stripped to just the stuff relevant 
to key watching. It doesn't work.  When it runs, it prints 
"Repetitive work" over and over, but never see anything appear in 
"cmd [ ]".  When I tap 'A' I expect to see "cmd [A]" and a line 
of several 'A'.  This does not happen.  But the writeln in 
cmdwatcher() does show whatever I typed just fine.


How to fix this, or redesign the whole thing to work?

Note that I'm coming from science and fine art. My know-how in 
computer science is uneven, and I probably have gaps in my 
knowledge about threads.



import std.stdio;
import core.stdc.stdio;  // for getchar().  There's nothing 
similar in D std libs?

import std.concurrency;
import core.thread; // just for sleep()

bool running=true;
char command = '?';

void cmdwatcher()
{
writeln("Key Watcher");
while (running)  {
char c = cast(char)getchar();
if (c>=' ')  {
command = c;
writefln(" key %c  %04X", c, c);
}
}
}

void main()
{
writeln("Start main");
spawn();

while (running) {
writeln("Repetitive work");
Thread.sleep( dur!("msecs")( 900 ) );

char cmd = command;  // local copy can't change during 
rest of this loop

command = ' ';
writefln("cmd [%c]  running %d", cmd, running);

switch (cmd)
{
case 'A':
writeln("A A A A A");
break;

case 'Q':
writeln("Quitting");
running=false;
break;
default:
break;
}
}
}