Error running concurrent process and storing results in array

Steven Schveighoffer schveiguy at gmail.com
Wed May 6 13:57:37 UTC 2020


On 5/6/20 2:49 AM, drug wrote:
> 06.05.2020 09:24, data pulverizer пишет:
>> On Wednesday, 6 May 2020 at 05:44:47 UTC, drug wrote:
>>>
>>> proc is already a delegate, so &proc is a pointer to the delegate, 
>>> just pass a `proc` itself
>>
>> Thanks done that but getting a range violation on z which was not 
>> there before.
>>
>> ```
>> core.exception.RangeError at onlineapp.d(3): Range violation
>> ----------------
>> ??:? _d_arrayboundsp [0x55de2d83a6b5]
>> onlineapp.d:3 void onlineapp.process(double, double, long, 
>> shared(double[])) [0x55de2d8234fd]
>> onlineapp.d:16 void onlineapp.main().__lambda1() [0x55de2d823658]
>> ??:? void core.thread.osthread.Thread.run() [0x55de2d83bdf9]
>> ??:? thread_entryPoint [0x55de2d85303d]
>> ??:? [0x7fc1d6088668]
>> ```
>>
> 
> confirmed. I think that's because `proc` delegates captures `i` variable 
> of `for` loop. I managed to get rid of range violation by using `foreach`:
> ```
> foreach(i; 0..n) // instead of for(long i = 0; i < n;)
> ```
> I guess that `proc` delegate cant capture `i` var of `foreach` loop so 
> the range violation doesn't happen.

foreach over a range of integers is lowered to an equivalent for loop, 
so that was not the problem.

Indeed, D does not capture individual for loop contexts, only the 
context of the entire function.

> 
> you use `proc` delegate to pass arguments to `process` function. I would 
> recommend for this purpose to derive a class from class Thread. Then you 
> can pass the arguments in ctor of the derived class like:
> ```
> foreach(long i; 0..n)
>      new DerivedThread(double)(i), cast(double)(i + 1), i, z).start(); 
> thread_joinAll();
> ```

This is why it works, because you are capturing the value manually while 
in the loop itself.

Another way to do this is to create a new capture context:

foreach(long i; 0 .. n)
    auto proc = (val => {
        process(cast(double)(val), cast(double)(val + 1), val, z);
    })(i);
    ...
}

-Steve


More information about the Digitalmars-d-learn mailing list