digitalmars.D.learn - Timeout around function call
- drathier (3/3) Sep 22 2020 What's the obvious way to put a timeout around a function call?
- =?UTF-8?Q?Ali_=c3=87ehreli?= (74/76) Sep 22 2020 I would start a thread and use receiveTimeout():
- Imperatorn (7/10) Sep 22 2020 You have several options. Either you use the actor model
- drathier (10/21) Sep 23 2020 Blocking is perfectly fine. I'm wondering if I need things to be
- Imperatorn (4/16) Sep 23 2020 No. You should not share anything. Personally I would just send a
- =?UTF-8?Q?Ali_=c3=87ehreli?= (21/23) Sep 23 2020 std.concurrency does not allow "mutable thread-local data"; so one needs...
- Imperatorn (4/10) Sep 23 2020 Sorry, I can't see the problem. Could you be more specific about
- Imperatorn (2/14) Sep 23 2020 Oops, I meant to reply to drathier
- drathier (15/31) Sep 27 2020 I need to:
What's the obvious way to put a timeout around a function call? I'm thinking a 5 or 30 second timeout, and I'm expecting it to pretty much never time out.
Sep 22 2020
On 9/22/20 2:32 AM, drathier wrote:> What's the obvious way to put a timeout around a function call? I'mthinking a 5 or 30 second timeout, and I'm expecting it to pretty much never time out.I would start a thread and use receiveTimeout(): import std.concurrency; import std.stdio; import std.exception; import core.thread; // Uncomment to see what happens upon time out. // version = doTimeout; void compute(int i) { version (doTimeout) { writeln("The thread is napping."); Thread.sleep(2.seconds); } ownerTid.send(i + 1); } void main() { auto worker = spawn(&compute, 42); const received = receiveTimeout( 1.seconds, (int result) { writefln!"Received the result: %s"(result); } ); enforce(received, "Timed out."); } The thread need not be one-shot: It can continue waiting for more messages until told to stop: import std.concurrency; import std.stdio; import std.exception; import core.thread; // Uncomment to see what happens upon time out. // version = doTimeout; struct Done { } void computer() { bool done = false; while (!done) { receive( (Done _) { done = true; }, (int i) { version (doTimeout) { writeln("The thread is napping."); Thread.sleep(2.seconds); } ownerTid.send(i + 1); } ); } } void main() { // This time we use spawnLinked() so that we will receive // a LinkTerminated message. And the name is different and // the argument will be passed later with send(). auto worker = spawnLinked(&computer); foreach (i; 0 .. 10) { worker.send(i); const received = receiveTimeout( 1.seconds, (int result) { writefln!"Received the result: %s"(result); } ); enforce(received, "Timed out."); } // Tell worker to stop. worker.send(Done()); // Wait for worker to terminate. receiveOnly!LinkTerminated(); } Ali
Sep 22 2020
On Tuesday, 22 September 2020 at 09:32:13 UTC, drathier wrote:What's the obvious way to put a timeout around a function call? I'm thinking a 5 or 30 second timeout, and I'm expecting it to pretty much never time out.You have several options. Either you use the actor model (spawn[Linked]) and send a termination message after a specified time. Or you use a task and check for yourTask.done(). Or you could create a Thread and check isRunning. (You didn't specify what you wanted to happen and if blocking was allowed or not)
Sep 22 2020
On Tuesday, 22 September 2020 at 21:55:51 UTC, Imperatorn wrote:On Tuesday, 22 September 2020 at 09:32:13 UTC, drathier wrote:Blocking is perfectly fine. I'm wondering if I need things to be shared now or something? Not used to programming with threads. Adding a shared modifier recursively onto every piece of data that needs it is a ton of work though. I don't want to copy the data around since it's many gigabytes, but I'm sure there won't be any data races; main thread will start 2 threads, one for running the timer and one running the function call. The main thread doesn't access the data until both the timer and function call threads have stopped completely.What's the obvious way to put a timeout around a function call? I'm thinking a 5 or 30 second timeout, and I'm expecting it to pretty much never time out.You have several options. Either you use the actor model (spawn[Linked]) and send a termination message after a specified time. Or you use a task and check for yourTask.done(). Or you could create a Thread and check isRunning. (You didn't specify what you wanted to happen and if blocking was allowed or not)
Sep 23 2020
On Wednesday, 23 September 2020 at 17:33:50 UTC, drathier wrote:On Tuesday, 22 September 2020 at 21:55:51 UTC, Imperatorn wrote:No. You should not share anything. Personally I would just send a message to request termination or use the solution provided with timeout.[...]Blocking is perfectly fine. I'm wondering if I need things to be shared now or something? Not used to programming with threads. Adding a shared modifier recursively onto every piece of data that needs it is a ton of work though. I don't want to copy the data around since it's many gigabytes, but I'm sure there won't be any data races; main thread will start 2 threads, one for running the timer and one running the function call. The main thread doesn't access the data until both the timer and function call threads have stopped completely.
Sep 23 2020
On 9/23/20 1:19 PM, Imperatorn wrote:No. You should not share anything. Personally I would just send a message to request termination or use the solution provided with timeout.std.concurrency does not allow "mutable thread-local data"; so one needs to cast to shared (assuming copying is not desired e.g. because it's expensive). I am modifying my second program[1] with these changes: The worker's receive() call mentions an element with shared ints: receive( // .. same as before // New message type: (shared(int)[] arr) { ownerTid.send(arr[0]); } ); The sender casts to shared and receives a shared(int): auto arr = new int[100]; worker.send(cast(shared)arr); writefln!"Received array result: %s"(receiveOnly!(shared(int))()); It is unfortunate that receiveOnly!int does not work because the returned int is just a copy. Well, at least we have a way of distinguishing int from shared(int). Is it useful? Ali [1] https://forum.dlang.org/post/rkdrql$2uht$1 digitalmars.com
Sep 23 2020
On Wednesday, 23 September 2020 at 20:44:51 UTC, Ali Çehreli wrote:On 9/23/20 1:19 PM, Imperatorn wrote:Sorry, I can't see the problem. Could you be more specific about what you want to achieve?[...]send a[...]with timeout. [...]
Sep 23 2020
On Wednesday, 23 September 2020 at 20:54:51 UTC, Imperatorn wrote:On Wednesday, 23 September 2020 at 20:44:51 UTC, Ali Çehreli wrote:Oops, I meant to reply to drathierOn 9/23/20 1:19 PM, Imperatorn wrote:Sorry, I can't see the problem. Could you be more specific about what you want to achieve?[...]send a[...]with timeout. [...]
Sep 23 2020
On Wednesday, 23 September 2020 at 20:58:00 UTC, Imperatorn wrote:On Wednesday, 23 September 2020 at 20:54:51 UTC, Imperatorn wrote:I need to: - call a side-effect-free fn with a huge argument that I don't want to copy; this argument is then returned mostly unmodified wrapped in a new value - stop executing it if it runs for more than x seconds - get the return value from it if it finishes within x seconds (99.9% of time time) - let the main thread know what happened - the main thread should block until the fn call returns - the fn call should for sure stop executing before the main thread carries on - the size and complexity of the fn makes it pretty much impossible to add timeout checks everywhere to make it exit nicely; I need to kill it to be sure I didn't miss a caseOn Wednesday, 23 September 2020 at 20:44:51 UTC, Ali Çehreli wrote:Oops, I meant to reply to drathierOn 9/23/20 1:19 PM, Imperatorn wrote:Sorry, I can't see the problem. Could you be more specific about what you want to achieve?[...]send a[...]with timeout. [...]
Sep 27 2020