-1

I'm trying to run some code asynchronously within my class (see: https://github.com/duncan3dc/fork-helper). I need to call a series of methods that will modify the values of my properties. I can't seem to do so. I'm trying to use the last example of the call() method on this page: https://duncan3dc.github.io/fork-helper/usage/getting-started/

<?php

class foobar
{
    private $x = 0;

    public function doubler(&$number_to_double)
    {
        $number_to_double = $number_to_double * 2;
    }

    public function index()
    {
        $fork = new \duncan3dc\Forker\Fork;
        $this->x    = 5;

        // outputs 5, as expected
        var_dump($this->x);

        $fork->call([$this, 'doubler'], $this->x);
        $fork->wait();

        // does not output 10, which is what I want
        var_dump($this->x);
    }
}

$my_foobar = new foobar();
$my_foobar->index();

I don't have to pass by reference, like I did in my doubler. Instead, I'm also open to just modifying the member from within the doubler method.

Why isn't my private member x doubling at the second var_dump()?

yivi
  • 42,438
  • 18
  • 116
  • 138
StackOverflowNewbie
  • 39,403
  • 111
  • 277
  • 441
  • 1
    Fork duplicates the memory space of a running program and since `x` is not in a shared memory location any modifications will not leak though the two processes. – apokryfos Dec 19 '19 at 09:14
  • See also : https://stackoverflow.com/questions/10871293/how-does-pcntl-fork-work-in-php while the library documentation mentions "mutli-threading" that is incorrect. It's multiple processes. – apokryfos Dec 19 '19 at 09:20
  • So, I should not be using `fork`? Or can I pass it the current value of my member, get a return value, then update the value of my member? – StackOverflowNewbie Dec 19 '19 at 09:28
  • The methods I need to call are loosely coupled enough that I think I could just get it to return a value that I need to set my properties. So, if I could `fork` and get a return value (or pass a variable by reference), I think I can make it work. How do I use this `fork` lib in that way? – StackOverflowNewbie Dec 19 '19 at 09:36
  • The comment by @apokryfos might be as well be an answer. There is nothing else to be done here. You can't modify variables process 1 and see that mutation in process 2, nor you can "return" a value from process 1 to process 2. – yivi Dec 19 '19 at 10:32
  • @apokryfos - turn your comment into an answer please. – StackOverflowNewbie Dec 19 '19 at 10:36

1 Answers1

2

The linked library seems to be internally using pcntl_fork which performs a true fork of the running PHP process. The library mentions "threading" but this is not correct. Forking is a pretty low level operating system concept whereas a process creates a copy of its memory space and instructions in a new process. That new process becomes a child process of the forking process.

This means that everything, like included code and instantiated objects are copied and therefore a child process cannot directly modify the objects of the parent process. The only ways a child process can communicate with the parent is shared memory. In addition the parent can "wait" for the child process to terminate (failing to do this may result in zombie child processes). The linked library does not seem to implement true shared memory but (if you must) you could probably use the PHP shared memory library.

This however is impractical for simple tasks like the one you're sharing. In your case you need to use a true threading library like e.g. pthreads. Threads, unlike processes, are part of the parent process and share the same memory and data structures and have a significantly lower overhead when context switching.

Note: All the above concepts are pretty low level ones so maybe PHP is not the best choice of language to implement these.

apokryfos
  • 38,771
  • 9
  • 70
  • 114