digitalmars.D.learn - How do I exhaust a thread's message queue?
- Andrej Mitrovic (28/28) Apr 01 2011 Note this is just pseudocode:
- Andrej Mitrovic (44/44) Apr 01 2011 I'm good at answering my own questions. :p
- Andrej Mitrovic (3/3) Apr 01 2011 Btw disregard that "handle" function, I've used it first but then
- Andrej Mitrovic (28/28) Apr 01 2011 Actually I have a bug in `foo()`, the switch statement is executed
- Andrej Mitrovic (10/10) Apr 02 2011 It turns out the receiveTimeout technique didn't work well for me. In
Note this is just pseudocode: // worker thread void doWork() { // while there's still stuff in the message queue while (messagesInQueue) { result = receiveOnly!int(); switch(result) { // main thread could be enabling or disabling features this way, // and sending some commands.. } } // now that we have all of our commands, do some hard work.. } // background Thread void main() { while (userHasMoreInputs()) { // send switches to the worker thread, via e.g.: workerThread.send(userValue); } } So I'm really interested in how to implement that line: while (messagesInQueue) Perhaps I have to use receiveTimeout?
Apr 01 2011
I'm good at answering my own questions. :p import std.stdio; import std.concurrency; import core.thread; void main() { auto workThread = spawn(&foo); int delay = 500; int command = 0; while(true) { Thread.sleep( dur!("msecs")( delay += 100 ) ); workThread.send(++command); } } void handle(int x) { writeln(x); } void foo() { int result; bool gotMessage; do { gotMessage = receiveTimeout(1000, (int x) { result = x; } ); switch (result) { case 1: writeln("one"); break; case 2: writeln("two"); break; default: writeln("something else"); break; } } while (gotMessage); writeln("Done!"); } I love how elegant D is.
Apr 01 2011
Btw disregard that "handle" function, I've used it first but then decided to change `result` directly in the receiveTimeout function. It's better that way.
Apr 01 2011
Actually I have a bug in `foo()`, the switch statement is executed even if I didn't get a message back. Here's a fix: void foo() { int result; bool gotMessage; while (true) { gotMessage = receiveTimeout(1000, (int x) { result = x; } ); if (!gotMessage) break; switch (result) { case 1: writeln("one"); break; case 2: writeln("two"); break; default: writeln("something else"); break; } } writeln("Done!"); }
Apr 01 2011
It turns out the receiveTimeout technique didn't work well for me. In my case, there's a timer which spawns a high-priority thread calling `foo` several hundred times per second. What I really needed is to exhaust the message queue, and then do some other work after that. So I've added a `shared int messagesInQueue`, which gets incremented in the main thread, and decremented in the work thread when it reads off those messages. But isn't something like this already implemented somewhere in core.thread or std.concurrency? All I want to do is check if there are /any/ messages in queue for the current thread.
Apr 02 2011