Reputation: 1190
I am currently wanting to learn and implement pthreads - github. I have compiled php7
with the necessary components and verified that thread-safety
is enabled. My current example code has 4 child classes that belong to parent class Canine
. How should I call the Thread
class accordingly to execute bark()
from all classes shown below at the same? Keeping in mind the ability to scale when classes grow from 4 to 100. Pools? Workers?
class Database {
private $_host;
private $_user;
private $_pass;
private $_dbname;
private $_dsn;
private $_options;
public static $pdo;
private $error;
private $stmt;
public function __construct() {
$this->_host = 'xxxxx';
$this->_user = 'xxxxx';
$this->_pass = 'xxxxx';
$this->_dbname = 'xxxxx';
$this->_dsn = 'mysql:host=' . $this->_host . ';dbname=' . $this->_dbname;
// Set options
$this->_options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true,
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_TIMEOUT => 1,
);
}
public function __sleep() {
return array('_dsn', '_user', '_pass');
}
public function __wakeup() {
$this->connect();
}
public function connect() {
try {
return self::$pdo = new PDO($this->_dsn, $this->_user, $this->_pass, $this->_options);
} catch (PDOException $e) {
$this->error = $e->getMessage();
}
}
}
class DataAccessObject {
protected $database;
public function __construct() {
//Create Instance of DB
$this->database = (new Database())->connect();
}
public function insertQuery($query) {
try {
$select = $this->database->prepare($query);
$select->execute();
$results = $select->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
echo "Failed: " . $e->getMessage();
}
return true;
}
}
class Helper extends DataAccessObject {
//code elided
}
abstract class Canine extends Helper {
abstract public function bark();
}
//Child Classes
class GoldenRitriever extends Canine {
public function bark() { echo 'arf-arf!<br>'; }
}
class Pitbull extends Canine {
public function bark() { echo 'ruff-ruff!<br>'; }
}
class GermanShepherd extends Canine {
public function bark() { echo 'wao-wao!<br>'; }
}
class LabradorRetriever extends Canine {
public function bark() { echo 'woof-woof!<br>'; }
}
Creating instances and invoking `bark()`
$golden_ritriever = new GoldenRitriever();
$golden_ritriever->bark();
$pitbull = new Pitbull();
$pitbull->bark();
$german_shepherd = new GermanShepherd();
$german_shepherd->bark();
$labrador_retriever = new LabradorRetriever();
$labrador_retriever->bark();
Upvotes: 2
Views: 1326
Reputation: 4680
I imagine that your problem is with the architecture of the solution i.e. you will have to extend the Thread class somewhere and are not sure where.
Assuming that the class structure (Helper, DataAccessObject) is final and that it does not make sense to extend DataAcessObject with Thread I would do it the following way.
class ThreadedCanine extends Thread {
private $canine;
public function __construct(Canine $canine) {
$this->canine = $canine;
}
public function run() {
$this->canine->bark();
}
}
$threads = [
new ThreadedCanine(new GoldenRitriever()),
new ThreadedCanine(new Pitbull()),
new ThreadedCanine(new GermanShepherd()),
new ThreadedCanine(new LabradorRetriever()),
];
foreach($threads as $thread) {
$thread->start();
}
foreach($threads as $thread) {
$thread->join();
}
I think this is a good way because it does not force a Canine to be a Thread as it might not need to be a thread all the time.
EDIT
I forgot to mention, in the original answer, that if you will want to scale to 100s of threads, yes, you should be using the Pool
and Worker
classes to manage that (the docs even recommend to use Worker instead of Thread), otherwise launching 100 threads simultaneously will not be good (and gets worse if you have multiple clients) :P
Once you get a better grasp of using Threads you can move to those scenarios.
Hope it helps :)
Upvotes: 4