Hi!
Yes, I expected the two functions - tsrm_new_interpreter() and
init_executor() to do that, as it is the function called in
php_request_startup() in main/main.c
As far as I remember, you need to run the whole request startup for the
the thread, otherwise there will be unitilialized pieces. TSRM magic
will create needed per-thread structures and call ctors, but ctors
usually just null out stuff, you'd still need to fill it in.
Another possible application would be a parallel_include() type call,
which would call a given PHP file for each member of an array (or a PDO
result set), buffering the output from each, and inserting into the
output stream in sequence once each fragment is done (hopefully
interacting well with normal output buffering, if you didn't want the
results sent yet). This would allow a large number of results to be
rendered in parallel on multicore systems.
That's what webservers do already, don't they? :)
I hope it will be possible to share already compiled code between
threads; this may mean disabling "eval" inside the thread or otherwise
The main problems you will be facing are the following:
1. All ZE structures are per-thread. This means using one thread's
structures in another will be non-trivial task, as all code assumes that
current thread's structures are used.
2. Even if you manage to hack around it by always passing the tsrm_ls
pointers, etc. - memory managers are per-thread too. Which means you
will be using data in one thread that is controlled by MM residing in
another thread. Without locking.
3. You may think this is not very bad, since you'll be using stuff
that's quite static, like classes and functions - they don't get
deallocated inside request, so who cares which MM uses them? However,
while classes themselves don't, structures containing them - hashtables
- can change, be rebuilt, etc. and if it happens in a wrong moment,
you're in trouble.
4. Next problem with using classes/functions is that they can contain
variables - zvals, as default properties, static variables, etc. Since
ZF is refcounting, these zvals may be modified by anybody who uses these
variables - even just for reading. Again, no locking. Which, again,
means trouble.
5. Then come resources and module globals. Imagine some function touches
in some way some resource - connection, file, etc. - that another thread
is using at the same time, without locking? Modules generally assume
resources belong to their respective threads, so you'll need to run
module initializations for each thread separately.
hobbling the compiler to avoid separate threads trying to modify the
optree at once. If a shared optree cannot be achieved, then I guess it
would have to go back to the APC, but it would be good to avoid
overheads where possible to keep the thread startup cost low.
Because of the things described above, it will be very challenging to
avoid those startup costs.
Even extremely restricted parallelism can help speed up some types of
work, so limitations I am happy to accept.
If you restrict it to using only copied data and never running any PHP
code, it might work. Alternatively, you might launch independent engine
instances that don't share structures and have them communicate, like
Erlang does. Though, unlike Erlang, PHP engine would not help you much
in this, I'm afraid.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php