Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
September 16, 2015 Best Direction on Spawning Process Async | ||||
---|---|---|---|---|
| ||||
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. |
September 16, 2015 Re: Best Direction on Spawning Process Async | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike McKee | 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 |
September 16, 2015 Re: Best Direction on Spawning Process Async | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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. |
September 16, 2015 Re: Best Direction on Spawning Process Async | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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. |
September 16, 2015 Re: Best Direction on Spawning Process Async | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike McKee | 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(); } |
Copyright © 1999-2021 by the D Language Foundation