Advertisement
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Returning to the main thread.

Comments in 'Plugin Development' started by Brutus, Sep 8, 2015.

  1. Brutus
    Offline

    Brutus New Member

    Joined:
    Aug 31, 2015
    Posts:
    21
    pthreads and PocketMine's extension of it offer a variety of multithreading options other than just using an AsyncTask.

    Is there a recommended way to schedule a task or otherwise trigger behavior on the main thread from another thread?

    Thank you.
  2. Andrey Nazarchuk
    Offline

    Andrey Nazarchuk Active Member

    Joined:
    Dec 30, 2013
    Posts:
    332
    Minecraft User:
    digita1eclipse
    I have this same exact question, like instead of $this->plugin using $this->main?
    Im pretty sure from all of @PEMapModder 's posts and some reading about pthreads that share-nothing model means you can't go back to main, main can only talk to plugin.
    I may be wrong but its whatever.
  3. Brutus
    Offline

    Brutus New Member

    Joined:
    Aug 31, 2015
    Posts:
    21
    Looking at how AsyncTasks are able to return to the main thread with onCompletion(), it seems like the main thread just checks the AsyncPool periodically for tasks that have finished.

    I do not know if there is any other way to "leave" something for the main thread to pick up on though.
  4. Andrey Nazarchuk
    Offline

    Andrey Nazarchuk Active Member

    Joined:
    Dec 30, 2013
    Posts:
    332
    Minecraft User:
    digita1eclipse
    maybe, Idk though, I only completed the php class on codeacademy.org 25% becayse of a glitch that did not allow me to move farther. I basically have no idea why async tasks don't share anything. I use this code to talk to other files which execute in other threads, but I guess it can be switched around:
    PHP:
      public function __construct($plugin){
        
    $this->plugin $plugin;parent::__construct($plugin);
      }
    Then just put $this->plugin in front of anything you want to do/get from inside main file.
    I have since learned to just do everything that needs to be done in main inside main.
  5. Gamecrafter
    Offline

    Gamecrafter

    Joined:
    Nov 20, 2014
    Posts:
    978
    Plugins:
    9
    You don't have any idea what you are talking about. So you shouldn't confuse @Brutus. I have no idea what he's talking about(mostly because I'm a noob :p), just wait for the pros to come.
    PEMapModder and Andrey Nazarchuk like this.
  6. Andrey Nazarchuk
    Offline

    Andrey Nazarchuk Active Member

    Joined:
    Dec 30, 2013
    Posts:
    332
    Minecraft User:
    digita1eclipse
    Exactly what I was saying... Idk why I even posted, perhaps just to get yelled at by you :p (Because that's always fun, though it's even more when shoghicp yells at you because then he gives you epic code as the best apology ever)
    I digress.
  7. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    That is a Task (synchronized task), not an AsyncTask. Doing that in an AsyncTask will lead to immediate lag or crash.

    Take a look at the CommandReader class in PocketMine source. It uses the \Threaded class from pthreads to share the data.
    Remember not to attempt to share any non-threaded objects between threads. Also, storing any objects as class properties of a Threaded class will, when in the main thread (not sure, but that's my observation), serialize it automatically (you need to serialize it if it doesn't, anyway), so remember not to set big objects (big on the "deep" (recursive) not the "shallow" perspective) or objects with reference (directly or indirectly) to unknown objects (like the main Server class or plugin main classes) as class properties.
    Brutus likes this.
  8. Brutus
    Offline

    Brutus New Member

    Joined:
    Aug 31, 2015
    Posts:
    21
    Just to make sure I am understanding this correctly, the strategy is to create a buffer that is shared across threads, serialize data into it from your async thread, and periodically check for and read that data from the main thread?

    It seems (maybe) like in CommandSender only one line is passed at a time. I will have to look more into using buffers to make sure I can pass multiple objects within the interval between checks.

    Does this mean any member of an AsyncTask class (ex: private $pluginMain) will be serialized, even if it is never referenced in onRun()?

    If so and we cannot maintain any references to "big" objects in AsyncTasks, doesn't this make it difficult to do a callback? I have seen other threads mentioning things like $server->getPluginManager()->getPlugin("PluginName")->processResult($data), but that is very inelegant to me.
    Last edited: Sep 9, 2015
  9. PEMapModder
    Offline

    PEMapModder Notable Member Plugin Developer

    Joined:
    Oct 9, 2013
    Posts:
    7,294
    Plugins:
    11
    Minecraft User:
    PEMapModder
    You can consider using static functions. Basically, you cannot and should not interact with the main server in other threads because that object cannot be shared between threads. You can by serializing it, but as you might already know, the pointers aren't shared like this:
    PHP:
    class NonThreadedClass{
      public 
    $property;
    }
    $obj = new NonThreadedClass;
    $obj->property "a";
    $newObj unserialize(serialize($obj));
    $newObj->property "b";
    var_dump($obj->property); // string(1) "a"
    Technically, we can call non-threaded objects shared between threads as "clones". Therefore, you cannot get anything useful by calling API functions (except those unrelated to the server itself, such as those in the pocketmine\utils\Utils class).

    You can actually do it in the onCompletion(Server) function, where you can get result from $this->getResult() (result is stored using setResult() in the other thread, where the result you passed is serialized and stored in a class property) and interact with the API (using the Server object passed in) with the value.

Share This Page

Advertisement