Variable modified by different threads.

Ali Çehreli acehreli at yahoo.com
Mon Dec 2 02:29:39 UTC 2024


On 12/1/24 6:23 PM, Andy Valencia wrote:
> On Monday, 2 December 2024 at 02:02:56 UTC, Ritina wrote:
>> How can I implement a program where I have a global integer variable 
>> g, and three threads: the first thread increments g by 1, the second 
>> thread increments g by 2, and the third thread increments g by 3? 
>> Additionally, while these threads are running, I should be able to 
>> access the value of g both inside and outside the threads.
> 
> Here's my own shared memory across multiple threads sample program,  It 
> does a fine job of thrashing that cache line!
> 
> ```
> import core.atomic : atomicFetchAdd;
> import std.concurrency : spawn;
> import core.time : msecs;
> import core.thread : Thread;
> import core.memory : GC;
> 
> const uint NSWEPT = 100_000_000;
> const uint NCPU = 4;
> 
> void
> doadd(shared uint *buf)
> {
>      for (uint count = 0; count < NSWEPT/NCPU; ++count) {
>          atomicFetchAdd(buf[0], 1);
>      }
> }
> 
> void
> main()
> {
>      shared uint *buf =
>          cast(shared uint *)GC.calloc(uint.sizeof * 1, GC.BlkAttr.NO_SCAN);
> 
>      for (uint x = 0; x < NCPU-1; ++x) {
>          spawn(&doadd, buf);
>      }
>      doadd(buf);
>      while (buf[0] != NSWEPT) {
>          Thread.sleep(1.msecs);
>      }
> }
> ```
> 

And here's mine which has interesting amount of differences:

import core.atomic;
import core.thread;
import std.concurrency;
import std.conv;
import std.stdio;

// This is the variable that will be incremented collectively.
shared int g;

// This is the variable that will signal the threads to stop.
shared bool stopRequested;

// This is the thread function.
void modify(int increment) {
     while (!stopRequested) {
         g.atomicOp!"+="(increment);
     }
}

void main() {
     // Spawn some threads.
     enum totalThreads = 3;

     foreach (i; 0 .. totalThreads) {
         const increment = (i + 1).to!int;
         spawnLinked(&modify, increment);
     }

     // Wait for a while to request them to stop.
     Thread.sleep(2.seconds);
     stopRequested = true;

     // Wait until all threads are stopped.
     size_t stopped = 0;
     while (stopped != totalThreads) {
         receive((LinkTerminated _) {
                 stopped++;
             });
     }

     // Print the final value of g.
     writefln!"%,s"(g);
}

I am not sure whether

   stopRequested = true

is correct even when there is a single writer of that variable. There 
are several other methods of communicating the request. I chose that one 
for this example.

Ali



More information about the Digitalmars-d-learn mailing list