Thread overview
Async messages to a thread.
Jul 29, 2013
lindenk
Jul 29, 2013
John Colvin
Jul 29, 2013
lindenk
Jul 29, 2013
lindenk
Jul 29, 2013
Sean Kelly
Jul 29, 2013
lindenk
Jul 29, 2013
Sean Kelly
Jul 29, 2013
John Colvin
July 29, 2013
Hello!
This is partially a general question as I don't know what this is called or if it exists. Say for example I want to do something like the following -

import std.concurrency;

void main()
{
    void foo() {
        try
        {
            while(true)
            {
                 do_some_blocking_function();
            }
        } catch(GotAMessage msg){}

        // clean up
    };

    tid = spawn(&foo, thisTid);

    // do stuff / wait for some condition

    send(tid, "STAHP!");
}

One solution I've used in the past is setting a timeout for the blocking function then polling to see if the thread should exit. The disadvantage is it causes extra, unnecessary checking and has a delay before it gets the message and exits.

This is a fairly simple example but the idea should be the same, is there a way to pass a message or signal to a thread to cause it to branch to some other location?
July 29, 2013
On Monday, 29 July 2013 at 15:28:45 UTC, lindenk wrote:
> Hello!
> This is partially a general question as I don't know what this is called or if it exists. Say for example I want to do something like the following -
>
> import std.concurrency;
>
> void main()
> {
>     void foo() {
>         try
>         {
>             while(true)
>             {
>                  do_some_blocking_function();
>             }
>         } catch(GotAMessage msg){}
>
>         // clean up
>     };
>
>     tid = spawn(&foo, thisTid);
>
>     // do stuff / wait for some condition
>
>     send(tid, "STAHP!");
> }
>
> One solution I've used in the past is setting a timeout for the blocking function then polling to see if the thread should exit. The disadvantage is it causes extra, unnecessary checking and has a delay before it gets the message and exits.
>
> This is a fairly simple example but the idea should be the same, is there a way to pass a message or signal to a thread to cause it to branch to some other location?

import std.concurrency;
import core.time;

void foo(Tid parent) {
    bool run = true;
    while(run)
    {
         //do_some_blocking_function();
         receiveTimeout(dur!"msecs"(0),
             (string s){if(s == "STAHP!") run = false;}
         );
    }

    // clean up
    send(parent, "done");
}


void main()
{
    auto tid = spawn(&foo, thisTid);

    // do stuff / wait for some condition

    send(tid, "STAHP!");
    auto msg = receiveOnly!(string)();
    assert(msg == "done");
}
July 29, 2013
> void foo(Tid parent) {
>     bool run = true;
>     while(run)
>     {
>          //do_some_blocking_function();
>          receiveTimeout(dur!"msecs"(0),
>              (string s){if(s == "STAHP!") run = false;}
>          );
>     }
>
>     // clean up
>     send(parent, "done");
> }
>
>
> void main()
> {
>     auto tid = spawn(&foo, thisTid);
>
>     // do stuff / wait for some condition
>
>     send(tid, "STAHP!");
>     auto msg = receiveOnly!(string)();
>     assert(msg == "done");
> }

Ah, no I mean, what if do_some_blocking_function blocks for some indeterminate amount of time. I would like it to exit even when it is currently blocking (as it could be unpredictable when it will stop blocking).
July 29, 2013
After a bit more research it looks like everyone else uses -

while(checkIfRunning())
{
    // block with timeout
}

which leads me to believe this might not be possible or standard. Although, should something along the lines of this be possible?

Process p = new Process();
p.doTask(p.func()); //create new thread and start function

// do stuff until this needs to exit

p.stop(); // halt running function,
p.cleanup(); // call a clean up function for func's resources
p.kill(); // forcibly kill the thread


If this is possible and/or not a bad idea, how can I accomplish this in D? (And if there isn't really a way, I feel like D's scope(exit) and such should work nicely with it).
July 29, 2013
On Jul 29, 2013, at 8:28 AM, lindenk <ztaticnull@gmail.com> wrote:
> 
> Ah, no I mean, what if do_some_blocking_function blocks for some indeterminate amount of time. I would like it to exit even when it is currently blocking (as it could be unpredictable when it will stop blocking).

Execute the blocking functions in a separate thread?  Really, this sounds like the kind of thing futures are for.  Alternately, maybe the sequence of blocking functions could call receive periodically, or maybe be executed in a fiber and yield periodically, etc.
July 29, 2013
On Jul 29, 2013, at 10:07 AM, lindenk <ztaticnull@gmail.com> wrote:

> After a bit more research it looks like everyone else uses -
> 
> while(checkIfRunning())
> {
>    // block with timeout
> }
> 
> which leads me to believe this might not be possible or standard. Although, should something along the lines of this be possible?

It sounds like you're maybe doing socket IO?  In those cases, you can open a pipe for signaling.  select() on whatever other socket plus the read end of the pipe, and if you want to break out of the blocking select() call, write a byte to the pipe.  Ultimately, std.concurrency should get some socket integration so data can arrive as messages, but that will never be as efficient as the approach I've described.

> Process p = new Process();
> p.doTask(p.func()); //create new thread and start function
> 
> // do stuff until this needs to exit
> 
> p.stop(); // halt running function,
> p.cleanup(); // call a clean up function for func's resources
> p.kill(); // forcibly kill the thread

Forcibly killing threads tends to be a pretty bad idea if you intend to keep running after the thread is killed.  It can even screw up attempts at a clean shutdown.
July 29, 2013
On Monday, 29 July 2013 at 17:26:55 UTC, Sean Kelly wrote:
> On Jul 29, 2013, at 10:07 AM, lindenk <ztaticnull@gmail.com> wrote:
>
>> After a bit more research it looks like everyone else uses -
>> 
>> while(checkIfRunning())
>> {
>>    // block with timeout
>> }
>> 
>> which leads me to believe this might not be possible or standard. Although, should something along the lines of this be possible?
>
> It sounds like you're maybe doing socket IO?  In those cases, you can open a pipe for signaling.  select() on whatever other socket plus the read end of the pipe, and if you want to break out of the blocking select() call, write a byte to the pipe.  Ultimately, std.concurrency should get some socket integration so data can arrive as messages, but that will never be as efficient as the approach I've described.
>
>> Process p = new Process();
>> p.doTask(p.func()); //create new thread and start function
>> 
>> // do stuff until this needs to exit
>> 
>> p.stop(); // halt running function,
>> p.cleanup(); // call a clean up function for func's resources
>> p.kill(); // forcibly kill the thread
>
> Forcibly killing threads tends to be a pretty bad idea if you intend to keep running after the thread is killed.  It can even screw up attempts at a clean shutdown.


The blocking function will sometimes be socket IO, it's set up to get data from whatever it is set to. That sounds promising though, I could set it up to do that when it is socket IO then have it poll when it isn't. Thanks!
July 29, 2013
On Monday, 29 July 2013 at 16:19:03 UTC, lindenk wrote:
>> void foo(Tid parent) {
>>    bool run = true;
>>    while(run)
>>    {
>>         //do_some_blocking_function();
>>         receiveTimeout(dur!"msecs"(0),
>>             (string s){if(s == "STAHP!") run = false;}
>>         );
>>    }
>>
>>    // clean up
>>    send(parent, "done");
>> }
>>
>>
>> void main()
>> {
>>    auto tid = spawn(&foo, thisTid);
>>
>>    // do stuff / wait for some condition
>>
>>    send(tid, "STAHP!");
>>    auto msg = receiveOnly!(string)();
>>    assert(msg == "done");
>> }
>
> Ah, no I mean, what if do_some_blocking_function blocks for some indeterminate amount of time. I would like it to exit even when it is currently blocking (as it could be unpredictable when it will stop blocking).

The blocking function could start in a new thread and do a receiveTimeout periodically, or you could make it stateful (if necessary) and return periodically and be restarted if it hasn't been asked to stop (which is just a very ugly and rudimentary version of what you'd want to do with fibers).

Or, if you don't care about making a mess, just kill the thread I guess.