こんにちは、haniokasaiです。
誰も、PocketMine-MPのマルチスレッドについてまとめた人がいなかったのでまとめてみます。
イントロ
phpで書かれたpocketmineは重いです。それは、保守のかんたんさと引き換えにそうなっているのでしょうが、特にcurlで外部のapiにアクセスをするものを使うときには全体の処理を遅らせてしまうことでしょう。
そもそも、PMMPのbinには、pthreadが同梱されていますが、単純に使うことはどうやら
できないようです。そこでどうしようかなぁと思ってたら、記憶がうろ覚えなのですが、pocketmine\threadを使うと良いと、おぎわらが教えてくれました。彼は私の夢で何故か一度登場したことがあります。
マルチスレッドについては、検索すればいい説明が読めます。
プラグイン例
https://github.com/haniokasai/PocketMine-Thread/
Thread
threadは、返り値の伴わないスレッド処理ができます。ですから、serverlistの情報送信のような一方的な作業に使うことができます。
$job1 = new thread_ex1("Hello");
$job1->start();
最初の $job1 = new thread_ex1("Hello");
で、仕事を生成します。
()内には、引き渡したい変数をかけます。
(引き渡し先は、_construct($data)です。この関数の中に $this->data = $data; と定義してあげると、run内で利用できます。)
$job1->start(); で仕事実行です。
すると、_construct、runの関数の順に実行されます。
ただし、run内で、phpで書いた関数はスレッドクラス外から呼び出せないです。
AsyncTask
これは動作完了時に、任意の作業をさせることができます。ですから、webに接続するタイプのログインプラグインであっても、通信が完了した時にログインを完了させれば、他の人がラグを感じずに済むわけです。
最初の、 $job4 = new thread_ex3(云々 の変数で、仕事を作成、scheduleAsyncTask で開始させています。
すると、_construct が実行、onRun が実行され、 onRunが完了すれば、onCompletionが実行されるでしょう。
onRun内では、外部の関数が実行できませんが、onCompletionでは、Serverの変数が渡されるので、$server を$this->getServer()として見なせば、pmmpが操作できます。
イントロの逆ってアウトロなんですね!
以上、マルチスレッドの方法について、まとめてみました。
サンプルプラグインを触れば、何ができるかよりわかると思います。
もともと、ある人の鯖の軽量化のためだけに考えたのですが、もうその人は鯖をやめてしまい、自分も開かないことをその人に進めたので、墓場(github)に埋もれていました。ですから、せっかくなので拾い上げ、記事にしました。
これで少しでも使う人が増えたらいいなと思います。今回はざっとしか書いてないですけど、反応を見て続編を書きたいです。
参考:
https://github.com/pmmp/PocketMine-MP/blob/master/src/pocketmine/scheduler/AsyncTask.php
https://github.com/organization/SpawningPool
お世話になった、おぎわら、ありがと!
https://twitter.com/CostlierRain464
誰も、PocketMine-MPのマルチスレッドについてまとめた人がいなかったのでまとめてみます。
イントロ
phpで書かれたpocketmineは重いです。それは、保守のかんたんさと引き換えにそうなっているのでしょうが、特にcurlで外部のapiにアクセスをするものを使うときには全体の処理を遅らせてしまうことでしょう。
そもそも、PMMPのbinには、pthreadが同梱されていますが、単純に使うことはどうやら
できないようです。そこでどうしようかなぁと思ってたら、記憶がうろ覚えなのですが、pocketmine\threadを使うと良いと、おぎわらが教えてくれました。彼は私の夢で何故か一度登場したことがあります。
マルチスレッドについては、検索すればいい説明が読めます。
プラグイン例
https://github.com/haniokasai/PocketMine-Thread/
Thread
threadは、返り値の伴わないスレッド処理ができます。ですから、serverlistの情報送信のような一方的な作業に使うことができます。
$job1 = new thread_ex1("Hello");
$job1->start();
class thread_ex1 extends Thread
{
public function _construct($data)
{
$this->data = $data;
}
public function run()
{
echo $this->data;
Server::getInstance()->getLogger()->notice($this->data);// 動かない、無言だがエラーとなる
}
}
最初の $job1 = new thread_ex1("Hello");
で、仕事を生成します。
()内には、引き渡したい変数をかけます。
(引き渡し先は、_construct($data)です。この関数の中に $this->data = $data; と定義してあげると、run内で利用できます。)
$job1->start(); で仕事実行です。
すると、_construct、runの関数の順に実行されます。
ただし、run内で、phpで書いた関数はスレッドクラス外から呼び出せないです。
これは動作完了時に、任意の作業をさせることができます。ですから、webに接続するタイプのログインプラグインであっても、通信が完了した時にログインを完了させれば、他の人がラグを感じずに済むわけです。
$this->getServer()->getScheduler()->scheduleAsyncTask($job4 = new thread_ex3(Server::getInstance()));
|
最初の、 $job4 = new thread_ex3(云々 の変数で、仕事を作成、scheduleAsyncTask で開始させています。
すると、_construct が実行、onRun が実行され、 onRunが完了すれば、onCompletionが実行されるでしょう。
onRun内では、外部の関数が実行できませんが、onCompletionでは、Serverの変数が渡されるので、$server を$this->getServer()として見なせば、pmmpが操作できます。
イントロの逆ってアウトロなんですね!
以上、マルチスレッドの方法について、まとめてみました。
サンプルプラグインを触れば、何ができるかよりわかると思います。
もともと、ある人の鯖の軽量化のためだけに考えたのですが、もうその人は鯖をやめてしまい、自分も開かないことをその人に進めたので、墓場(github)に埋もれていました。ですから、せっかくなので拾い上げ、記事にしました。
これで少しでも使う人が増えたらいいなと思います。今回はざっとしか書いてないですけど、反応を見て続編を書きたいです。
参考:
https://github.com/pmmp/PocketMine-MP/blob/master/src/pocketmine/scheduler/AsyncTask.php
https://github.com/organization/SpawningPool
お世話になった、おぎわら、ありがと!
https://twitter.com/CostlierRain464
AsyncTaskについて
返信削除onRun()内では別スレッド上で行いたい処理を記述し、onCompletion()内ではメインスレッド上で行いたい処理を記述できます
なので、onRun()内で、メインスレッド上で動くServerの関数を呼び出すことはできません
なお、スレッドを無駄に生成すると、メモリに負担がかかるので、なるべくAsyncTaskを継承したクラスを定義して、使うことが勧められます。