Page 1 of 1

How to specify a thread where to execute a function ?

Posted: Mon Jun 15, 2020 2:00 pm
by PGilbert
Hello, I have a callback that is executed on a separate thread that needs to execute a particular function on thread 0 (UI thread for me). Is it possible to specify a thread where to execute an Apl function from another thread?

Thanks.

Re: How to specify a thread where to execute a function ?

Posted: Tue Jun 16, 2020 7:56 am
by MikeHughes
Hi Pierre

I hope you are well.

I'm afraid I don't think that is possible but if its UI updates you want then I believe Data Binding doesn't respect threading so you can set up a databinding between your thread and thread 0 and this will update your UI.

Michael

Re: How to specify a thread where to execute a function ?

Posted: Tue Jun 16, 2020 7:59 am
by StefanoLanzavecchia
You'll have to hand craft the behaviour you want. If your thread 0 is waiting on a []DQ, you can []NQ a custom event from your callback and have the []DQ react to that. If your thread 0 is actively executing other logic, then there's no way to interleave extra code.

If your callback needs the code executed in thread 0 to return a result or even just complete before the extra thread can continue with its logic, I recommend using []TGET/[]TPUT to synchronise execution and exchanging data between the two threads.

Re: How to specify a thread where to execute a function ?

Posted: Tue Jun 16, 2020 12:34 pm
by PGilbert
Thanks Michael and Stefano for your answers. I was hoping there was a ⎕Txx to do that or with spawn (&) you could somehow specify the thread to execute the function.

Re: How to specify a thread where to execute a function ?

Posted: Wed Jun 17, 2020 3:10 pm
by crishog
It's easy to spawn new threads, but I take it you want to preserve some information from previously executed steps, or run with a specific environment of settings.

There isn't a simple quad function to "poke" into a thread, because what is the thread doing while it is waiting for you to send it something to process? It has to be waiting for a command in some way or it will just terminate.

What is needed to do this is the set of token handling functions TPUT, TGET, and to a lesser extent TPOOL & TREQ. I have used this approach several times, notably in DFS. The rest of this post is a quick overview of roughly how it could work.

The main APL thread spawns one or more - let's call them worker threads. It generates a set of numbers to use as tokens & pass each thread a unique token as it is created (it's not a good idea to try to pass things to a thread via its own number).

Each worker thread's top level function has a simple loop (I use a :Repeat / :Until so I can pass it a terminating condition if required) at the top of which is a TGET which will promptly wait for an occurrence of its token in the pool.

As the main thread acquires a task which it needs to pass to a worker it puts the details into a number of variables in a namespace & supplies this as the left argument to a TPUT with a right argument of the token associated with the thread it wants to allocate the job to - it could be based simply on lightest load (e.g. fewest occurrences of a token in the pool) or to a specific thread to keep operations in sequence (e.g. to keep file operations in the order received, the main thread just has to keep a variable linking a file to a token, so that all operations for a single file are sent to one thread).

The worker cannot reply directly to the main thread (as it cannot wait without causing a deadlock), but details of how to reply, for example to a client via Conga, can be included in the namespace passed to the thread. Once the operation is complete, the function returns to the TGET to wait for its next instruction.

You cannot supply a function as the left argument to TPUT, but you can either give it a pointer to a command in a known set, an executable string, or a namespace containing a function.

And that is probably as clear as mud, but the TPUT/TGET combination is a simple & robust way of allocating tasks to worker threads. I can try to explain more clearly if you think this approach would help.

Re: How to specify a thread where to execute a function ?

Posted: Thu Jun 18, 2020 3:45 am
by PGilbert
Thanks Cris, this is helping.