Search code examples
multithreadinguser-interfacethread-safetyd

Sending messages from thread to thread without waiting


I have a program that has 2 threads, 1 for GUI, another for working in background. It's a server, that needs a GUI (can't explain why), and it reports some of the incoming buffers to the GUI. For that, the worker thread is running all the time, can't pause, or the clients will timeout.

So the problem is: I can't figure out how to send/receive messages from threads, without waiting. Something like: check if a message arrived (every 1000msecs), if yes, then that message contains a string that has to be 'pushed' to GUI, if not, go on. And this runs in GUI, so it must not wait, or the OS will 'think' the program is not responding.
The send and receive in D wait for messages to arrive, which I don't want.

What I've tried:
declare a variable in a module's namespace, then the main thread, and worker, both can access it. Something like:

import std.concurrency;
import std.stdio;

ubyte someVar;

void main(){
    //main thread:
    //spawn child thread
    writeln("someVar in thread#0:",&someVar);
    spawn(&childThread);
}

void childThread(){
    writeln("someVar in thread#1:",&someVar);
}

BUT, I've found out, using the code above, that each thread gets to have its own someVar.
Something else I tried:
I tried sending the pointer to someVar (from above example) as a message to worker thread, right after starting the thread, and receive messages in the worker thread, as soon as it starts (so no messages are missed). But, I found out that passing thread-local data is not allowed in D.

To sum it all up: How can I pass messages (string) from thread to thread, without putting the receiving thread to wait for messages?


Solution

  • BUT, I've found out, using the code above, that each thread gets to have its own someVar.

    In D, variables are thread-local unless they're marked as shared. So, if you wanted to use a variable like that to share data, you'd have to declare it as shared and deal with locking the variable appropriately. If you really want to do that, I'd suggest reading

    http://ddili.org/ders/d.en/concurrency_shared.html

    However, std.concurrency was designed with message passing in mind, and it has the send and receive functions for exactly that, avoiding the need for shared. receive blocks while waiting for a message, but you can use receiveTimeout instead, and per the documentation, if the timeout is negative, it won't wait at all. If you want to go that route (which is the recommended way to deal with threads talking to one another in D), then I suggest that you read this:

    http://ddili.org/ders/d.en/concurrency.html