digitalmars.D.learn - How do I exhaust a thread's message queue?
- Andrej Mitrovic <none none.none> Apr 01 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> Apr 01 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> Apr 01 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> Apr 01 2011
- Andrej Mitrovic <andrej.mitrovich gmail.com> Apr 02 2011
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









Andrej Mitrovic <andrej.mitrovich gmail.com> 