www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Best Direction on Spawning Process Async

reply Mike McKee <volomike gmail.com> writes:
What's the best direction from...

http://dlang.org/phobos/std_process.html

...on spawning an async process and then peeking at it 
occasionally as it runs, and then get notified when it finishes? 
In other words, what std.process functions would you recommend I 
use? What I want to avoid is a blocking state where the GUI 
freezes because it's waiting for the process to complete.

For instance, imagine you are building a front end GUI (like 
GtkD) to a command-line based antivirus scanner. You'll want to 
spawn the process, show a progress bar, and as the command line 
returns status information, you peek at it asynchronously and 
then update the progress bar (or perhaps store virus detected 
info in a table), and then stop the progress bar at 100% when the 
command process has finished.
Sep 15 2015
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 09/15/2015 09:21 PM, Mike McKee wrote:
 What's the best direction from...

 http://dlang.org/phobos/std_process.html

 ...on spawning an async process and then peeking at it occasionally as
 it runs, and then get notified when it finishes? In other words, what
 std.process functions would you recommend I use? What I want to avoid is
 a blocking state where the GUI freezes because it's waiting for the
 process to complete.

 For instance, imagine you are building a front end GUI (like GtkD) to a
 command-line based antivirus scanner. You'll want to spawn the process,
 show a progress bar, and as the command line returns status information,
 you peek at it asynchronously and then update the progress bar (or
 perhaps store virus detected info in a table), and then stop the
 progress bar at 100% when the command process has finished.
Sounds like an easy task for std.concurrency: import std.stdio; import std.concurrency; import core.thread; struct Progress { int percent; } struct Done { } void doWork() { foreach (percent; 0 .. 100) { Thread.sleep(100.msecs); if (!(percent % 10)) { ownerTid.send(Progress(percent)); } } ownerTid.send(Done()); } void main() { auto worker = spawn(&doWork); bool done = false; while (!done) { bool received = false; while (!received) { received = receiveTimeout( // Zero timeout is a non-blocking message check 0.msecs, (Progress message) { writefln("%s%%", message.percent); }, (Done message) { writeln("Woohoo!"); done = true; }); if (!received) { // This is where we can do more work Thread.sleep(42.msecs); write(". "); stdout.flush(); } } } } Ali
Sep 16 2015
next sibling parent Mike McKee <volomike gmail.com> writes:
Beautiful, Ali. Took me a bit to read here...

http://dlang.org/phobos/std_concurrency.html

...but I realized that receiveTimeout() was a std.concurrency 
class method.
Sep 16 2015
prev sibling parent reply Mike McKee <volomike gmail.com> writes:
This really shows the beauty and simplicity of the D language 
compared to C++. Check this out in Qt/C++:

http://stackoverflow.com/questions/32593463/spawn-async-qprocess-from-dynamic-library-peek-output-until-done

...see how much nicer the D version is here that Ali did, versus 
the Qt/C++ technique.
Sep 16 2015
parent cka <not-an address.com> writes:
On Wednesday, 16 September 2015 at 16:30:46 UTC, Mike McKee wrote:
 This really shows the beauty and simplicity of the D language 
 compared to C++. Check this out in Qt/C++:

 http://stackoverflow.com/questions/32593463/spawn-async-qprocess-from-dynamic-library-peek-output-until-done

 ...see how much nicer the D version is here that Ali did, 
 versus the Qt/C++ technique.
Here is an alternative Qt sample to handle the output of a process line by line and to get notified when it finishes: #include <QCoreApplication> #include <QProcess> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QProcess scanner; QObject::connect(&scanner, &QProcess::readyRead, [&] { while (!scanner.atEnd()) { auto line = scanner.readLine(); // process line } }); // select the QProcess::finished(int) overload void (QProcess::*finishedSignal)(int) = &QProcess::finished; QObject::connect(&scanner, finishedSignal, [] (int) { // proces finished QCoreApplication::quit(); }); scanner.start("avscanner"); return a.exec(); }
Sep 16 2015