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

  • Variable modifie... Ritina via Digitalmars-d-learn
    • Re: Variabl... Andy Valencia via Digitalmars-d-learn
      • Re: Var... Ali Çehreli via Digitalmars-d-learn
        • Re:... Andy Valencia via Digitalmars-d-learn
        • Re:... Salih Dincer via Digitalmars-d-learn
          • ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
            • ... Salih Dincer via Digitalmars-d-learn
              • ... Ali Çehreli via Digitalmars-d-learn
              • ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
                • ... Nick Treleaven via Digitalmars-d-learn
                • ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
                • ... Ali Çehreli via Digitalmars-d-learn
                • ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

Reply via email to