digitalmars.D.learn - Capture context surrounding delegate
- Python (100/100) May 09 Too much code below, but I cannot reduce it more. The issue is in
- Nick Treleaven (3/15) May 10 This is a known issue with capturing variables scoped in a loop:
- Tim (18/24) May 10 This is a known issue. See e.g.
- Python (5/7) May 10 Wow, the original issue is 17 years old.
- Justin Allen Parrott (2/3) May 12 I don’t like this
- Python (3/6) May 12 Poor man's tool to keep my threads running.
- Justin Allen Parrott (2/9) May 12 Thread-wait or join
Too much code below, but I cannot reduce it more. The issue is in
the main function, I want to pass a delegate to a thread with a
captured value from the surrounding context. At least this was my
expectation, the delegate should capture any stack value.
Am I doing something wrong?
(please ignore lock abuse, I know that are better ways to do it,
let's concentrate on problem at hand).
```d
import std.stdio;
import core.thread;
void main()
{
for (int i = 0; i < 100; ++i)
{
auto captured = i;
//how do i capture i?
//it's always 99 (or near when first threads are spawned
before
//for cycle ends)
ThreadPool.enqueue(() {
writefln("Item: %d on thread %d, running %d threads",
captured, Thread.getThis.id, ThreadPool.threads);
});
}
writeln("all enqueued");
getchar();
}
struct ThreadPool
{
private static __gshared _queue_lock = new Object();
private static __gshared _thread_lock = new Object();
private static __gshared const(void delegate())[] _queue;
private static __gshared int threads;
private static __gshared int _minThreads = 1;
private static __gshared int _maxThreads = 10;
private static auto dequeue()
{
synchronized(_queue_lock)
{
if (_queue.length > 0)
{
auto item = _queue[0];
_queue = _queue[1 .. $];
return item;
}
else
{
return null;
}
}
}
static void enqueue(void delegate() item)
{
synchronized(_queue_lock)
{
_queue ~= item;
}
resizeIfNeeded();
}
private static void resizeIfNeeded()
{
synchronized(_thread_lock)
{
if (threads < _maxThreads)
{
synchronized(_queue_lock)
{
if (_queue.length > 0)
{
new Thread(&run).start();
++threads;
}
}
}
}
}
private static void run()
{
while (true)
{
auto item = dequeue();
if (item !is null)
{
item();
}
else
{
synchronized(_thread_lock)
{
if (threads > _minThreads)
{
--threads;
break;
}
}
}
}
}
}
```
May 09
On Saturday, 10 May 2025 at 04:52:15 UTC, Python wrote:
for (int i = 0; i < 100; ++i)
{
auto captured = i;
//how do i capture i?
//it's always 99 (or near when first threads are
spawned before
//for cycle ends)
ThreadPool.enqueue(() {
writefln("Item: %d on thread %d, running %d
threads", captured, Thread.getThis.id, ThreadPool.threads);
});
}
This is a known issue with capturing variables scoped in a loop:
https://issues.dlang.org/show_bug.cgi?id=21929#c10
May 10
On Saturday, 10 May 2025 at 04:52:15 UTC, Python wrote:Too much code below, but I cannot reduce it more. The issue is in the main function, I want to pass a delegate to a thread with a captured value from the surrounding context. At least this was my expectation, the delegate should capture any stack value. Am I doing something wrong?This is a known issue. See e.g. https://github.com/dlang/dmd/issues/18108 A workaround is to put the loop body in an additional function, which is directly called: ```d for (int i = 0; i < 100; ++i) { (){ auto captured = i; ThreadPool.enqueue(() { writefln("Item: %d on thread %d, running %d threads", captured, Thread.getThis.id, ThreadPool.threads); }); }(); } ```
May 10
On Saturday, 10 May 2025 at 11:35:41 UTC, Tim wrote:This is a known issue. See e.g. https://github.com/dlang/dmd/issues/18108Wow, the original issue is 17 years old. https://issues.dlang.org/show_bug.cgi?id=2043 At least I know that not my threading stuff is causing this. Thanks.
May 10
On Saturday, 10 May 2025 at 04:52:15 UTC, Python wrote:
getchar();
I don’t like this
May 12
On Monday, 12 May 2025 at 08:35:02 UTC, Justin Allen Parrott wrote:On Saturday, 10 May 2025 at 04:52:15 UTC, Python wrote:Poor man's tool to keep my threads running.getchar();I don’t like this
May 12
On Monday, 12 May 2025 at 14:10:41 UTC, Python wrote:On Monday, 12 May 2025 at 08:35:02 UTC, Justin Allen Parrott wrote:Thread-wait or joinOn Saturday, 10 May 2025 at 04:52:15 UTC, Python wrote:Poor man's tool to keep my threads running.getchar();I don’t like this
May 12









Nick Treleaven <nick geany.org> 