2
votes

I am experimenting with pthreads in PHP. Referencing Joe's gist covering pools, I create a pool of worker threads, and submit instances of stackable objects. The threads and work all go as I expect, however it seems that the main thread/context does not (fully) dereference the Stackable objects, so memory usage increases indefinitely as it keeps more and more instances around.

It does seem to clear/nullify all of the properties of the stackable object, so memory usage doesn't quickly go through the roof, but it does increase forever, so this effectively can't be used for a long-running process. I hope I am just doing something wrong. Here is sample code that will demonstrate what I mean:

class W extends Worker {
    public function run(){}
}
class S extends Stackable {
    public $id;
    public function run() {
        $this->id = uniqid();
    }
    public function __destruct () {
        // $this->id will be null here when the main thread destroys its copy of this
        if ($this->id === null) {
            echo "nullified stackable destroyed\n";
        } else {
            echo "stackable {$this->id} destroyed\n";
        }
    }
}

$pool = new Pool(3, W::class);
$i = 0;
while ($i++ < 10) {
    $pool->submit(new S());
}
sleep(1); // to let threads finish

$pool->collect(function (S $s) {
    echo "collected stackable {$s->id}\n";
    return true;
});
$pool->shutdown();
echo "script exit - here come the destructions of all the accumulated stackables\n";
1
That's what I was afraid of. - Justin McAleer

1 Answers

1
votes

Many improvements have come to pthreads v3 as part of the upgrade for PHP7.

You will find the PHP7 version of this code works as expected:

<?php
class W extends Worker {
    public function run(){}
}
class S extends Threaded implements Collectable {
    public $id;

    public function run() {
        $this->id = uniqid();
        $this->garbage = true;
    }

    public function __destruct () {
        if ($this->id === null) {
            echo "nullified stackable destroyed\n";
        } else {
            echo "stackable {$this->id} destroyed\n";
        }
    }

    public function isGarbage() : bool { return $this->garbage; }

    private $garbage = false;
}

$pool = new Pool(3, W::class);
$i = 0;
while ($i++ < 10) {
    $pool->submit(new S());
}

while ($pool->collect(function (S $s) {
    if ($s->isGarbage()) {
        echo "collected stackable {$s->id}\n";
    }
    return $s->isGarbage();
})) continue;

$pool->shutdown();
echo "script exit - here come the destructions of all the accumulated stackables\n";

It is recommended that new projects use PHP7 and pthreads v3, it is vastly superior to PHP5 and pthreads v2.