Coder Social home page Coder Social logo

pthreads's Introduction

Threading for PHP - Share Nothing, Do Everything :)

Build Status Build status Average time to resolve an issue Percentage of issues still open Join the chat at https://gitter.im/krakjoe/pthreads

This project provides multi-threading that is compatible with PHP based on Posix Threads.

Highlights

  • An easy to use, quick to learn OO Threading API for PHP 7.2+
  • Execute any and all predefined and user declared methods and functions, including closures.
  • Ready made synchronization included
  • A world of possibilities ...

Technical Features

  • High Level Threading
  • Synchronization
  • Worker Threads
  • Thread Pools
  • Complete Support for OO - ie. traits, interfaces, inheritance etc
  • Full read/write/execute support for Threaded objects

Requirements

  • PHP 7.2+
  • ZTS Enabled ( Thread Safety )
  • Posix Threads Implementation

Testing has been carried out on x86, x64 and ARM, in general you just need a compiler and pthread.h

PHP7

For PHP7, pthreads has been almost completely rewritten to be more efficient, easier to use and more robust. I will give a brief changelog here:

The API for v3 has changed, the following things have been removed:

  • Mutex, Cond, and Stackable
  • Threaded::lock and Threaded::unlock
  • Threaded::isWaiting
  • Threaded::from
  • Thread::kill (there be dragons)
  • Thread::detach
  • Worker::isWorking
  • Threaded::getTerminationInfo (this was unsafe, a better, safe impl can be done in userland)
  • Special behaviour of protected and private methods on Threaded objects

The following things have significant changes:

  • The method by which Threaded objects are stored as member properties of other Threaded objects.
  • The structure used by a Worker for stack (Collectable objects to execute inserted by Worker::stack).
  • The Pool::collect mechanism was moved from Pool to Worker for a more robust Worker and simpler Pool inheritance.
  • The method by which iteration occurs on Threaded objects, such that it uses memory more efficiently.
  • Threaded::synchronized provides true synchronization (state and properties lock).
  • Worker objects no longer require that you retain a reference to Collectable objects on the stack.
  • Unified monitor (cond/mutex/state) for Threaded objects
  • Threaded members of Threaded objects are immutable
  • Volatile objects, exempt from immutability
  • array coerced to Volatile when set as member of Threaded
  • Collectable converted to interface, to make extends Volatile implements Collectable possible.

Some blog posts explaining these changes:

Supported PHP Versions

pthreads v3 requires PHP7 or above. PHP5 needs to use pthreads v2 which can be found in the PHP5 branch.

Note that only PHP 7.2+ is now supported (requiring the current master branch of pthreads). This is due to safety issues with ZTS mode on PHP 7.0 and 7.1.

Unix-based Building from Source

Building pthreads from source is quite simple on Unix-based OSs. The instructions are as follows:

  • Clone this repository and checkout the release to use (or master for the latest updates)
  • cd pthreads
  • phpize
  • ./configure
  • make
  • make install (may need sudo)
  • Update your php.ini file to load the pthreads.so file using the extension directive

Windows Support

Yes !! Windows support is offered thanks to the pthread-w32 library.

Releases for Windows can be found: http://windows.php.net/downloads/pecl/releases/pthreads/

Simple Windows Installation
  • Add pthreadVC2.dll (included with the Windows releases) to the same directory as php.exe eg. C:\xampp\php
  • Add php_pthreads.dll to PHP extension folder eg. C:\xampp\php\ext

Mac OSX Support

Yes !! Users of Mac will be glad to hear that pthreads is now tested on OSX as part of the development process.

Hello World

As is customary in our line of work:

<?php
$thread = new class extends Thread {
	public function run() {
		echo "Hello World\n";
	}
};

$thread->start() && $thread->join();
?>

Are you serious ?

Absolutely, this is not a hack, we don't use forking or any other such nonsense, what you create are honest to goodness posix threads that are completely compatible with PHP and safe ... this is true multi-threading :)

SAPI Support

pthreads v3 is restricted to operating in CLI only: I have spent many years trying to explain that threads in a web server just don't make sense, after 1,111 commits to pthreads I have realised that, my advice is going unheeded.

So I'm promoting the advice to hard and fast fact: you can't use pthreads safely and sensibly anywhere but CLI.

Thanks for listening ;)

Documentation

Documentation can be found in the PHP manual: http://docs.php.net/manual/en/book.pthreads.php, and some examples can be found in the "examples" folder in the master repository.

Further insights and occasional announcements can be read at the http://pthreads.org site where pthreads is developed and tested in the real world.

Here are some links to articles I have prepared for users: everybody should read them before they do anything else:

If you have had the time to put any cool demo's together and would like them showcased on pthreads.org please get in touch.

Polyfill

It's possible to write code that optionally takes advantage of parallelism where the environment has pthreads loaded.

This is made possible by pthreads-polyfill which can be found on packagist.

Having required the appropriate package in your composer.json, the following code is executable everywhere:

<?php
require_once("vendor/autoload.php");

if (extension_loaded("pthreads")) {
	    echo "Using pthreads\n";
} else  echo "Using polyfill\n";

$pool = new Pool(4);

$pool->submit(new class extends Threaded {
        public function run() {
                echo "Hello World\n";
        }
});

while ($pool->collect()) continue;

$pool->shutdown();
?>

Some guidance on getting started, and detail regarding how the polyfill came to exist can be found here.

Feedback

Please submit issues, and send your feedback and suggestions as often as you have them.

Reporting Bugs

If you believe you have found a bug in pthreads, please open an issue: Include in your report minimal, executable, reproducing code.

Minimal: reduce your problem to the smallest amount of code possible; This helps with hunting the bug, but also it helps with integration and regression testing once the bug is fixed.

Executable: include all the information required to execute the example code, code snippets are not helpful.

Reproducing: some bugs don't show themselves on every execution, that's fine, mention that in the report and give an idea of how often you encounter the bug.

It is impossible to help without reproducing code, bugs that are opened without reproducing code will be closed.

Please include version and operating system information in your report.

Please do not post requests to help with code on github; I spend a lot of time on Stackoverflow, a much better place for asking questions.

Have patience; I am one human being.

Developers

There is no defined API for you to create your own threads in your extensions, this project aims to provide Userland threading, it does not aim to provide a threading API for extension developers. I suggest you allow users to decide what they thread and keep your own extension focused on your functionality.

pthreads's People

Contributors

2072 avatar bwoebi avatar chibisuke avatar davidgoodwin avatar dktapps avatar ephrin avatar gitter-badger avatar hfedcba avatar jan-e avatar krakjoe avatar laruence avatar lisachenko avatar mcmrarm avatar msjyoo avatar olekukonko avatar peehaa avatar petk avatar pgbezerra avatar phpbakery avatar prolic avatar reeze avatar remicollet avatar rtheunissen avatar saleemkce avatar sirsnyder avatar stricted avatar tpunt avatar vikash avatar wagnert avatar zelgerj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pthreads's Issues

ld: 4 duplicate symbols for architecture x86_64

Hi,

i've tried to compile a new version with your latest changes on Mac OS X 10.7.5 and got the following error:

/Users/wagnert/Downloads/pthreads/src/object.c:579:37: warning: format specifies type 'unsigned long ' but the argument has type 'PTHREAD *' (aka 'struct pthread_construct *') [-Wformat]
if (sscanf((const char
)buffer, "%lu", &address)) {
~~^ ~~~~~~~~
1 warning generated.
/bin/sh /Users/wagnert/Downloads/pthreads/libtool --mode=link cc -DPHP_ATOM_INC -I/Users/wagnert/Downloads/pthreads/include -I/Users/wagnert/Downloads/pthreads/main -I/Users/wagnert/Downloads/pthreads -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib -I/Users/wagnert/Downloads/pthreads/. -DHAVE_CONFIG_H -g -O2 -o pthreads.la -export-dynamic -avoid-version -prefer-pic -module -rpath /Users/wagnert/Downloads/pthreads/modules php_pthreads.lo src/lock.lo src/globals.lo src/prepare.lo src/synchro.lo src/state.lo src/store.lo src/resources.lo src/modifiers.lo src/handlers.lo src/object.lo
cc ${wl}-flat_namespace ${wl}-undefined ${wl}suppress -o .libs/pthreads.so -bundle .libs/php_pthreads.o src/.libs/lock.o src/.libs/globals.o src/.libs/prepare.o src/.libs/synchro.o src/.libs/state.o src/.libs/store.o src/.libs/resources.o src/.libs/modifiers.o src/.libs/handlers.o src/.libs/object.o
duplicate symbol _pthreads_globals_id in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _pthreads_globals_id in:
.libs/php_pthreads.o
src/.libs/prepare.o
duplicate symbol _pthreads_globals_id in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol pthreads_globals_id in:
.libs/php_pthreads.o
src/.libs/object.o
ld: 4 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *
* [pthreads.la] Error 1

Thanks for having a look at it :)

Windows version for PHP 5.4 missing

Downloading pthreads-0.38-php-5.4.zip leads to a 'File was not found.' I compiled my own one, but maybe you should upload it once again.

Thanks for an extension that opens a lot of possibilities!

Unable to store Stream resources in Thread object

As soon as I assign a stream resource to a thread object member the stream resource gets somehow damaged.

class fw_reader extends Thread {
    public function run() {
        $stream = fopen('c:\windows\system32\drivers\etc\hosts','r');
        $this->socket = $stream;
        stream_set_blocking($this->socket, true);
        stream_set_timeout($this->socket, 2);
    }
}

$fw_r = new fw_reader();
$fw_r->start();
$fw_r->join();

error message is:
Warning: stream_set_timeout(): 2 is not a valid stream resource in P:\php\test.php on line 6

Using PHP 5.4, pthreads [245dbb1] on windows

If I change $this->socket to $stream it works fine.Also if I reverse the order of the "steam_set_blocking" and the "stream_set_timeout the error happens on the stream_set_blocking command and if I add a print_r($this->socket) before the steam_set_ it happens on both.

Any idea?

EDIT: I can confirm the same problem also happening with Stackable objects (instread Thread), while it works if using global scope

Polling/waiting for an array of Stackables/Threads

I've been playing around with this code alongside non-blocking streams and I find myself missing a select() style call.

It would be nice to be able to give a function an array of Stackable/Thread and have the function return when one or more of the elements becomes ready, perhaps copying the style of stream_select.

At the moment I can just wait() on the first item in the list, but that isn't ideal. It seems as though a select-like function would work nicely here, although I would be interested to hear other ideas.

Thanks for the code—it's been fun to play with!

Segmentation fault

I become with the current code a segmentation fault:

segfault at ffffffff ip 00000000006eb9af sp 00007fff8a696430 error 4 in php5

#14 still exists

ld: 67 duplicate symbols for architecture x86_64

duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/lock.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/lock.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/lock.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/lock.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/lock.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/lock.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/lock.o
duplicate symbol _pthreads_globals in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/globals.o
duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/prepare.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/prepare.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/prepare.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/prepare.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/prepare.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/prepare.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/prepare.o
duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/synchro.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/synchro.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/synchro.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/synchro.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/synchro.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/synchro.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/synchro.o
duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/state.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/state.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/state.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/state.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/state.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/state.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/state.o
duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/store.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/store.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/store.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/store.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/store.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/store.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/store.o
duplicate symbol _pthreads_globals in:
.libs/php_pthreads.o
src/.libs/store.o
duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/modifiers.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/modifiers.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/modifiers.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/modifiers.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/modifiers.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/modifiers.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/modifiers.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol _pthreads_globals in:
.libs/php_pthreads.o
src/.libs/handlers.o
duplicate symbol _pthreads_handlers in:
.libs/php_pthreads.o
src/.libs/object.o
duplicate symbol _pthreads_thread_entry in:
.libs/php_pthreads.o
src/.libs/object.o
duplicate symbol _pthreads_worker_entry in:
.libs/php_pthreads.o
src/.libs/object.o
duplicate symbol _pthreads_stackable_entry in:
.libs/php_pthreads.o
src/.libs/object.o
duplicate symbol _pthreads_mutex_entry in:
.libs/php_pthreads.o
src/.libs/object.o
duplicate symbol _pthreads_condition_entry in:
.libs/php_pthreads.o
src/.libs/object.o
duplicate symbol _zend_handlers in:
.libs/php_pthreads.o
src/.libs/object.o
duplicate symbol _pthreads_globals in:
.libs/php_pthreads.o
src/.libs/object.o

pthreads.so cannot be loaded: undefined symbol sapi_globals_id

So, I am having problems with pthreads and mod_php 5.6.4 in Ubuntu 12.10 x64.

Apache error log says the following: pthreads.so cannot be loaded: undefined symbol sapi_globals_id in Unknown on line 0

I tried to compile pthreads statically into PHP with the following commands:

henri@ubuntu:~/php5-5.4.6/ext$ ./buildconf --force

and

henri@ubuntu:~/php5-5.4.6$ ./configure --with-pthreads --with-tsrm-pthreads --enable-maintainer-zts

So what am I missing?

PHP Segmentation fault

It seems pthreads is somewhat unstable in my system. I am running a web crawler (via CRON), which was originally implemented by procedual style programming and now with pthreads I have used the Async:call("my_function", array($parameters)); method for doing some crawling and storing data at the same time.

This could be, for example creating 30 curl threads and then creating a thread for saving data from previous loop to mySQL database at the same time. And after the curl threads have finished, I would unset / set them=NULL and start analyzing the data, again by creating 30 different threads (and unsetting them after getting the results).

Now, this seems to work, lets say, about 4-5 minutes and would bring a very noticeable performance benefit but then the scripts ends with a segmentation fault. On some cases, no segmentation fault occurs but the scripts own log shows that every threaded CURL-request simply fails same as connecting to the database, which results in an "Failed to create unix socket" exception.

It is entirely possible that I am actually doing something wrong, but I would love to have your insight in this problems since its keeping me awake at nigths. An earlier version was implemented with pcntl-forks, which seemed to work fine, however the difficulties of returning "large" amount of data from another process made me looking for an another way to do multithreading.

I am running Ubuntu 12.10 x64 with PHP 5.4.6 CGI/FastCGI and pthreads compiled as a static extension. The php's configure command is following:

'./configure' '--prefix=/usr' '--enable-pthreads=static' '--enable-maintainer-zts' '--with-mysql' '--with-mysqli' '--with-sqlite' '--with-sqlite3' '--enable-pdo' '--with-pdo-mysql' '--with-pdo-sqlite' '--enable-mbstring' '--with-curl'

when I run examples, A lot of PHP Notices show up

My PHP version is PHP 5.4.8.
pthreads is already the newest.

My configure is:
Configure Command => './configure' '--prefix=/usr/local/Cellar/php54/5.4.8' '--localstatedir=/usr/local/var' '--sysconfdir=/usr/local/etc/php/5.4' '--with-config-file-path=/usr/local/etc/php/5.4' '--with-config-file-scan-dir=/usr/local/etc/php/5.4/conf.d' '--with-iconv-dir=/usr' '--enable-dba' '--with-ndbm=/usr' '--enable-exif' '--enable-soap' '--enable-wddx' '--enable-ftp' '--enable-sockets' '--enable-zip' '--enable-pcntl' '--enable-shmop' '--enable-sysvsem' '--enable-sysvshm' '--enable-sysvmsg' '--enable-mbstring' '--enable-mbregex' '--enable-bcmath' '--enable-calendar' '--with-zlib=/usr/local/Cellar/zlib/1.2.7' '--with-ldap' '--with-ldap-sasl=/usr' '--with-xmlrpc' '--with-kerberos=/usr' '--with-xsl=/usr' '--with-curl=/usr/local/Cellar/curl/7.28.0' '--with-gd' '--enable-gd-native-ttf' '--with-freetype-dir=/usr/local/Cellar/freetype/2.4.10' '--with-mcrypt=/usr/local/Cellar/mcrypt/2.5.8' '--with-jpeg-dir=/usr/local/Cellar/jpeg/8d' '--with-png-dir=/usr/local/Cellar/libpng/1.5.13' '--with-gettext=/usr/local/Cellar/gettext/0.18.1.1' '--with-snmp=/usr' '--with-libedit' '--mandir=/usr/local/Cellar/php54/5.4.8/share/man' '--with-mhash' '--enable-maintainer-zts' '--enable-zend-signals' '--enable-dtrace' '--with-libxml-dir=/usr/local/Cellar/libxml2/2.8.0' '--with-bz2=/usr' '--disable-debug' '--with-openssl=/usr' '--enable-fpm' '--with-fpm-user=_www' '--with-fpm-group=_www' '--with-mssql=/usr/local/Cellar/freetds/0.91' '--with-pdo-dblib=/usr/local/Cellar/freetds/0.91' '--with-mysql-sock=/tmp/mysql.sock' '--with-mysqli=mysqlnd' '--with-mysql=mysqlnd' '--with-pdo-mysql=mysqlnd' '--with-iodbc' '--with-pdo-odbc=generic,/usr,iodbc'

Here are the PHP Notices:

PHP Notice: Constant mcrypt_encrypt already defined in Unknown on line 0

Notice: Constant mcrypt_encrypt already defined in Unknown on line 0
PHP Notice: Constant mcrypt_decrypt already defined in Unknown on line 0

Notice: Constant mcrypt_decrypt already defined in Unknown on line 0
PHP Notice: Constant mcrypt_dev_random already defined in Unknown on line 0

Notice: Constant mcrypt_dev_random already defined in Unknown on line 0
PHP Notice: Constant mcrypt_dev_urandom already defined in Unknown on line 0

Notice: Constant mcrypt_dev_urandom already defined in Unknown on line 0
PHP Notice: Constant mcrypt_rand already defined in Unknown on line 0

Notice: Constant mcrypt_rand already defined in Unknown on line 0
PHP Notice: Constant mcrypt_3des already defined in Unknown on line 0

Notice: Constant mcrypt_3des already defined in Unknown on line 0
PHP Notice: Constant mcrypt_arcfour_iv already defined in Unknown on line 0

Notice: Constant mcrypt_arcfour_iv already defined in Unknown on line 0
PHP Notice: Constant mcrypt_arcfour already defined in Unknown on line 0

Notice: Constant mcrypt_arcfour already defined in Unknown on line 0
PHP Notice: Constant mcrypt_blowfish already defined in Unknown on line 0

Notice: Constant mcrypt_blowfish already defined in Unknown on line 0
PHP Notice: Constant mcrypt_blowfish_compat already defined in Unknown on line 0

Notice: Constant mcrypt_blowfish_compat already defined in Unknown on line 0
PHP Notice: Constant mcrypt_cast_128 already defined in Unknown on line 0

Notice: Constant mcrypt_cast_128 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_cast_256 already defined in Unknown on line 0

Notice: Constant mcrypt_cast_256 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_crypt already defined in Unknown on line 0

Notice: Constant mcrypt_crypt already defined in Unknown on line 0
PHP Notice: Constant mcrypt_des already defined in Unknown on line 0

Notice: Constant mcrypt_des already defined in Unknown on line 0
PHP Notice: Constant mcrypt_enigna already defined in Unknown on line 0

Notice: Constant mcrypt_enigna already defined in Unknown on line 0
PHP Notice: Constant mcrypt_gost already defined in Unknown on line 0

Notice: Constant mcrypt_gost already defined in Unknown on line 0
PHP Notice: Constant mcrypt_loki97 already defined in Unknown on line 0

Notice: Constant mcrypt_loki97 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_panama already defined in Unknown on line 0

Notice: Constant mcrypt_panama already defined in Unknown on line 0
PHP Notice: Constant mcrypt_rc2 already defined in Unknown on line 0

Notice: Constant mcrypt_rc2 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_rijndael_128 already defined in Unknown on line 0

Notice: Constant mcrypt_rijndael_128 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_rijndael_192 already defined in Unknown on line 0

Notice: Constant mcrypt_rijndael_192 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_rijndael_256 already defined in Unknown on line 0

Notice: Constant mcrypt_rijndael_256 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_safer64 already defined in Unknown on line 0

Notice: Constant mcrypt_safer64 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_safer128 already defined in Unknown on line 0

Notice: Constant mcrypt_safer128 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_saferplus already defined in Unknown on line 0

Notice: Constant mcrypt_saferplus already defined in Unknown on line 0
PHP Notice: Constant mcrypt_serpent already defined in Unknown on line 0

Notice: Constant mcrypt_serpent already defined in Unknown on line 0
PHP Notice: Constant mcrypt_threeway already defined in Unknown on line 0

Notice: Constant mcrypt_threeway already defined in Unknown on line 0
PHP Notice: Constant mcrypt_tripledes already defined in Unknown on line 0

Notice: Constant mcrypt_tripledes already defined in Unknown on line 0
PHP Notice: Constant mcrypt_twofish already defined in Unknown on line 0

Notice: Constant mcrypt_twofish already defined in Unknown on line 0
PHP Notice: Constant mcrypt_wake already defined in Unknown on line 0

Notice: Constant mcrypt_wake already defined in Unknown on line 0
PHP Notice: Constant mcrypt_xtea already defined in Unknown on line 0

Notice: Constant mcrypt_xtea already defined in Unknown on line 0
PHP Notice: Constant mcrypt_idea already defined in Unknown on line 0

Notice: Constant mcrypt_idea already defined in Unknown on line 0
PHP Notice: Constant mcrypt_mars already defined in Unknown on line 0

Notice: Constant mcrypt_mars already defined in Unknown on line 0
PHP Notice: Constant mcrypt_rc6 already defined in Unknown on line 0

Notice: Constant mcrypt_rc6 already defined in Unknown on line 0
PHP Notice: Constant mcrypt_skipjack already defined in Unknown on line 0

Notice: Constant mcrypt_skipjack already defined in Unknown on line 0
PHP Notice: Constant mcrypt_mode_cbc already defined in Unknown on line 0

Notice: Constant mcrypt_mode_cbc already defined in Unknown on line 0
PHP Notice: Constant mcrypt_mode_cfb already defined in Unknown on line 0

Notice: Constant mcrypt_mode_cfb already defined in Unknown on line 0
PHP Notice: Constant mcrypt_mode_ecb already defined in Unknown on line 0

Notice: Constant mcrypt_mode_ecb already defined in Unknown on line 0
PHP Notice: Constant mcrypt_mode_nofb already defined in Unknown on line 0

Notice: Constant mcrypt_mode_nofb already defined in Unknown on line 0
PHP Notice: Constant mcrypt_mode_ofb already defined in Unknown on line 0

Notice: Constant mcrypt_mode_ofb already defined in Unknown on line 0
PHP Notice: Constant mcrypt_mode_stream already defined in Unknown on line 0

Notice: Constant mcrypt_mode_stream already defined in Unknown on line 0

STDIN, STDOUT, STDERR are not copied

Yes, I know, this are resources, NULL'ed because this aren't complex types, but I'd prefer if they are defined to the right ressources, even if it needs duplication.

Yes, this is a minor change and an user can work around with fopen("php://std..."), but it is simply expected that they exist.

Windows version

Hi there,
I'm not able to start PHP with this extension. What compiler you have used?
Can this be used on VC9 TS version?
Thanks
Ricardo

Problem with inheritance and interfaces

Please look at the following code.

When you start it from Windows XP commandline: php -f test.php, then PHP crash at parent::__construct
If you remove $objEvent from setEvent function and run from commadline it looks like php falls into infinite loop because processor utilization reaches 100% and program hangs up.
But when you remove from parent class "implemens IEvent" everything works ok.
PHP version 5.3.5

interface IEvent {

public function setEvent( $objEvent );

}

class parentClass implements IEvent {

    public function __construct() {

    }

    public function setEvent( $objEvent ) {

    }


}

class childClass extends parentClass {

    public function __construct() {

        parent::__construct();

    }

}

class clientThread extends Thread {


    public function run() {

        $objChild = new childClass();                

    }


}

$objClientThread = new clientThread();
$objClientThread->start();

Acces to private property

Tested on Windows commandline, PHP 5.3.5, snapshot: http://pthreads.org/snapshots/5.3/9690d1e579059bdd3f5a04a2068b613d0e1eb715.zip

This code raise notice:

PHP Notice: Undefined property: childClass::$var in C:\test.php on line 13

class parentClass {

    private $var;

    public function __construct() {

        echo $this->var;

    }

}

class childClass extends parentClass {

}

class clientThread extends Thread {

    public function run() {

        $objChild = new childClass();

    }               

}


$objClientThread = new clientThread();
$objClientThread->start();

Installation fails on OS X

make fails on my box.

Mac OS X 10.7.5
PHP 5.4.7 (cli) (built: Nov 8 2012 15:08:36)
XDebug and APC installed.

git clone git://github.com/krakjoe/pthreads.git
cd pthreads
phpize
./configure
make

/bin/sh /Users/osman/pthreads/libtool --mode=link cc -DPHP_ATOM_INC -I/Users/osman/pthreads/include -I/Users/osman/pthreads/main -I/Users/osman/pthreads -I/usr/local/Cellar/php54/5.4.7/include/php -I/usr/local/Cellar/php54/5.4.7/include/php/main -I/usr/local/Cellar/php54/5.4.7/include/php/TSRM -I/usr/local/Cellar/php54/5.4.7/include/php/Zend -I/usr/local/Cellar/php54/5.4.7/include/php/ext -I/usr/local/Cellar/php54/5.4.7/include/php/ext/date/lib -I/Users/osman/pthreads/.  -DHAVE_CONFIG_H  -g -O2   -o pthreads.la -export-dynamic -avoid-version -prefer-pic -module -rpath /Users/osman/pthreads/modules  php_pthreads.lo src/globals.lo src/prepare.lo src/synchro.lo src/state.lo src/store.lo src/modifiers.lo src/handlers.lo src/object.lo 
cc ${wl}-flat_namespace ${wl}-undefined ${wl}suppress -o .libs/pthreads.so -bundle  .libs/php_pthreads.o src/.libs/globals.o src/.libs/prepare.o src/.libs/synchro.o src/.libs/state.o src/.libs/store.o src/.libs/modifiers.o src/.libs/handlers.o src/.libs/object.o  
duplicate symbol _pthreads_globals in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _defmutex in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _pthreads_thread_entry in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _pthreads_worker_entry in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _pthreads_stackable_entry in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _pthreads_mutex_entry in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _pthreads_condition_entry in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _pthreads_exception_entry in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _pthreads_handlers in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _zend_handlers in:
    .libs/php_pthreads.o
    src/.libs/globals.o
duplicate symbol _defmutex in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _pthreads_thread_entry in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _pthreads_worker_entry in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _pthreads_stackable_entry in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _pthreads_mutex_entry in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _pthreads_condition_entry in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _pthreads_exception_entry in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _pthreads_handlers in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _zend_handlers in:
    .libs/php_pthreads.o
    src/.libs/synchro.o
duplicate symbol _pthreads_thread_entry in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _pthreads_worker_entry in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _pthreads_stackable_entry in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _pthreads_mutex_entry in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _pthreads_condition_entry in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _pthreads_exception_entry in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _pthreads_handlers in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _zend_handlers in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _defmutex in:
    .libs/php_pthreads.o
    src/.libs/prepare.o
duplicate symbol _defmutex in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _pthreads_thread_entry in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _pthreads_worker_entry in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _pthreads_stackable_entry in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _pthreads_mutex_entry in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _pthreads_condition_entry in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _pthreads_exception_entry in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _pthreads_handlers in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _zend_handlers in:
    .libs/php_pthreads.o
    src/.libs/state.o
duplicate symbol _defmutex in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _pthreads_thread_entry in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _pthreads_worker_entry in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _pthreads_stackable_entry in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _pthreads_mutex_entry in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _pthreads_condition_entry in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _pthreads_exception_entry in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _pthreads_handlers in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _zend_handlers in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _pthreads_globals in:
    .libs/php_pthreads.o
    src/.libs/store.o
duplicate symbol _defmutex in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _pthreads_thread_entry in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _pthreads_worker_entry in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _pthreads_stackable_entry in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _pthreads_mutex_entry in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _pthreads_condition_entry in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _pthreads_exception_entry in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _pthreads_handlers in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _zend_handlers in:
    .libs/php_pthreads.o
    src/.libs/modifiers.o
duplicate symbol _zend_handlers in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_thread_entry in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_worker_entry in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_stackable_entry in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_mutex_entry in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_condition_entry in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_exception_entry in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_handlers in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _defmutex in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_globals in:
    .libs/php_pthreads.o
    src/.libs/handlers.o
duplicate symbol _pthreads_handlers in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _defmutex in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _pthreads_thread_entry in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _pthreads_worker_entry in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _pthreads_stackable_entry in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _pthreads_mutex_entry in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _pthreads_condition_entry in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _pthreads_exception_entry in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _zend_handlers in:
    .libs/php_pthreads.o
    src/.libs/object.o
duplicate symbol _pthreads_globals in:
    .libs/php_pthreads.o
    src/.libs/object.o
ld: 76 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [pthreads.la] Error 1

Missing array property

Code to reproduce:

class Message extends Stackable {

    public $message;

    public function run() {

    }

    public function addMessage($message) {

        $this->message[] = $message;

        print_r( $this->message );
        print_r( $this->message[0] );
        echo $this->message[0];
    }

}

$message = new Message();
$message->addMessage( 'Hello World!' );

Expected result: you can see if you remove "extends Stackable" from code.
If $message is not an array everything is ok.

Unable to assign SimpleXML object to thread/stackable

you get

Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in
followed by a segfault.

code to reproduce:

class test extends Thread {
    public function run() {
        $this->x = new SimpleXMLElement('<test></test>');
    }
}

$test = new test();
$test->start();
$test->join();
Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in P:\php\test.php:5
Stack trace:
#0 P:\php\test.php(5): test::run()
#1 [internal function]: test->run()
#2 {main}
  thrown in P:\php\test.php on line 5
Segmentation fault

running php 5.4 pthreads 99f3d41 on windows

Usage of php multithreading..

Hi,

I'm pretty new to php and I have a problem that I think php multithreading can solve.. But I want to take your opinions about that. If that's really usable in my situation or not.

I've a shopping card written in php to sell pdf files. The code sends customer information to a seperate wordpress plugin via post method and receives the stamped pdf url back. There is a simple post function that does this job. (the plugin stamps customer info's to the pdf, generates a new pdf and sends the url back to the function)

The problem is that the function does this job about 3-4 seconds and I have 8 other functions waiting below that.. (we need to stamp multiple pdf files)

Doing them 1 by 1 takes a lot of times.

I've written seperate functions that send each pdf to different plugins.. So everything is set up.. Except, each function waits the previous one to be ended.. And that's taking too much time..

Can I use php multithreading as an option to solve this problem?

Any help and guidance would be more than welcomed.
Warm Regards.

Thread cannot be restarted after it has ended

When trying to restart the same thread after is has ended I get the warning that the thread has already been startet.

Is there any particular reason for this behavior I'm not seeing right away or is this a bug?
Also I don't yet get the point of the "Started" flag. Shouldn't "running" be enougth?

<?php
class Testcase extends Thread {
        function run() {
                echo "Start\n";
                Sleep(5);
                echo "End\n";
        }
}

$thread = new Testcase();
$thread->start();
while($thread->isRunning()) {
        echo '+';
        usleep(500);
}
echo "stopped\n";
$thread->start();
?>

Warning message

Warning: pthreads has detected an attempt to start Testcase (34405907456) that has already been started in /root/pth_test3.php on line 17

Singleton Bug

First, your project seems to be really really interesting. I'm waiting for someone start a project like this for the last three years. I hope you get succeed in your journal. You has my attention doing such a big thing and very hopeful for a lot of projects.

I'm putting down a problem I has in my enviroment. Seems when i try use static variables segfault shows up. I think this is because the PHPs architecture are not ready for this stuff. If you need more information for this, please, email me.

<?php

class BugThread {
        public static $instance;
        public static function get() {
                if (!self::$instance)
                        self::$instance = new self;
                return self::$instance;
        }
}

BugThread::get();

class IRQLThread extends Thread {
        public function run() {
                echo 1;
        }
}

$irqlThread = new IRQLThread();
$irqlThread->start();
$irqlThread->join();
[fernando@localhost ~]$ php test.php 
Segmentation fault (core dumped)

latest version not working anymore

I just tried updating to the latest version from git, but pthreads is not throwing fatal errors even in the simples testcases.

Fatal error: pthreads has suffered an internal error and cannot continue in /root/x.php on line 9

start(); $x->join(); ?>

The host OS is a FreeBSD 9.1 system and I compiled it against a clean php 5.4.8
[root@GameSrv /usr/local/src/php-5.4.8]# php-config
Usage: /usr/local/bin/php-config [OPTION]
Options:
--prefix [/usr/local]
--includes [-I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib]
--ldflags [ -L/usr/local/lib]
--libs [-lcrypt -lcrypt -liconv -liconv -lrt -lm -lxml2 -lz -liconv -lm -lxml2 -lz -liconv -lm -lxml2 -lz -liconv -lm -lcrypt -lxml2 -lz -liconv -lm -lxml2 -lz -liconv -lm -lxml2 -lz -liconv -lm -lcrypt ]
--extension-dir [/usr/local/lib/php/extensions/debug-zts-20100525]
--include-dir [/usr/local/include/php]
--man-dir [/usr/local/php/man]
--php-binary [/usr/local/bin/php]
--php-sapis [ cli fpm cgi]
--configure-options [--enable-maintainer-zts --enable-pthreads --enable-mbstring --enable-sockets --enable-fpm --enable-debug --with-mysql --enable-pthread_helper]
--version [5.4.8]
--vernum [50408]

Anything else I can help with troubleshooting the issue?

Calling incorrect methods and incorrect context

A new object is created (extends Thread) and runs it in a new Thread
$server = new ServerAPI(); $server->start(); $server->join();

Then, this is the run() method:

    public function run(){
        $this->load(); //Line 32
        $this->init();
    }

I've a public method called "load()"... But then PHP throws this error:

Fatal error: pthreads detected an attempt to call private method ServerAPI::load from outside the threading context in C:\Users\shoghicp\PocketMine-MP\src\API\ServerAPI.php on line 32

Wondering why it fails, and changing load() to a private method, and also why I'm outside the threading context, I inspect the entire class.

So, I found a method called "loadProperties()"... that's private. i change it to public and then... runs.

So there are two issues:

  • Incorrect context
  • Incorrect method calling

I've tested this with pthreads 0.38, and later 0.40. I'm using the XAMPP provided PHP build.

phpinfo() [CLI]

phpinfo()
PHP Version => 5.4.7

System => Windows NT SHOGHICP-LAPTOP 6.1 build 7601 (Windows 7 Home Premium Edition Service Pack 1) i586
Build Date => Sep 12 2012 23:44:56
Compiler => MSVC9 (Visual C++ 2008)
Architecture => x86
Configure Command => cscript /nologo configure.js  "--enable-snapshot-build" "--disable-isapi" "--enable-debug-pack" "--without-mssql" "--without-pdo-mssql" "--without-pi3web" "--with-pdo-oci=C:\php-sdk\oracle\instantclient10\sdk,shared" "--with-oci8=C:\php-sdk\oracle\instantclient10\sdk,shared" "--with-oci8-11g=C:\php-sdk\oracle\instantclient11\sdk,shared" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--with-mcrypt=static" "--disable-static-analyze" "--with-pgo"
Server API => Command Line Interface
Virtual Directory Support => enabled
Configuration File (php.ini) Path => C:\Windows
Loaded Configuration File => C:\xampp\php\php.ini
Scan this dir for additional .ini files => (none)
Additional .ini files parsed => (none)
PHP API => 20100412
PHP Extension => 20100525
Zend Extension => 220100525
Zend Extension Build => API220100525,TS,VC9
PHP Extension Build => API20100525,TS,VC9
Debug Build => no
Thread Safety => enabled
Zend Signal Handling => disabled
Zend Memory Manager => enabled
Zend Multibyte Support => provided by mbstring
IPv6 Support => enabled
DTrace Support => disabled

Registered PHP Streams => php, file, glob, data, http, ftp, zip, compress.zlib, compress.bzip2, phar
Registered Stream Socket Transports => tcp, udp
Registered Stream Filters => convert.iconv.*, mcrypt.*, mdecrypt.*, string.rot13, string.toupper, string.tolower, string.strip_tags, convert.*, consumed, dechunk, zlib.*, bzip2.*

This program makes use of the Zend Scripting Language Engine:
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies```

More userfriendly

Hi I am very excited to see someone stepping up to the plate and producing a significantly more viable solution to multi-threading in PHP. I am worried that this is a little over-complicated and does not work as user's would expect it to work.

I would like to help on this project although I am a novice in C. I have slightly hacked the source to make it work better for how i'd expect it to work.

My questions are simple:

  1. Are you willing to take suggestions on implementation of this project?
  2. Would you like some help in the codding of this project?

comments:

  1. This project is new and I figured it might be cool to work "outside the box" a little bit for some of the implementation of these functions rather than following the same way POSIX's pthreads does it. This could make it act more as you'd think PHP would treat it.

  2. As I said before I am still learning C, but I know many other languages and written only a few C/C++ programs, but I would be happy to assist a little in some of the implementation.

-Nathan

PHP Fatal error: Cannot access protected property

Hi,

we're working on a multithreaded application with a structure nearly the same as shown in the example below. In version 0.40-rc the example worked, with the new version i got the following fatal error:

[04-Jan-2013 14:29:20 Europe/Berlin] PHP Fatal error: Cannot access protected property Configuration::$type in /Users/wagnert/Workspace/Threads/memcached-server.php on line 92

As i don't try to access the property directly, but over the getter i think this should work as it still works with 0.40-rc. You can start the example on the commandline with php -f .php. Actually i'm working on a MacBook Pro, with Mac OS X 10.7.5 and PHP 5.4.10.

Example:

request = $request; } public function run() { if ($this->worker) { $request = $this->request; $sendQueue = msg_get_queue(1235); $response = new stdClass(); $response->uid = $request->uid; $response->body = 'Response: ' . $request->body; msg_send($sendQueue, $response->uid, $response, true); error_log("Successfully processed request " . $this->worker->getThreadId()); } } ``` } class SomeContainer { ``` protected $recKey = 1234; protected $recQueue = null; protected $requests = 0; protected $workers = array(); public function __construct() { $this->recQueue = msg_get_queue($this->recKey); for ($i = 0; $i < 4; $i++) { $this->workers[$i] = new RequestHandler($this); $this->workers[$i]->start(); } } public function start() { $requests = array(); while (true) { msg_receive($this->recQueue, 0, $msgtype, 1024, $request, true); $response = new stdClass(); $response->uid = $request->uid; $response->body = 'Response: ' . $request->body; $z = rand(0, sizeof($this->workers) - 1); $this->workers[$z]->stack($requests[] = new Request($request)); } } ``` } class RequestHandler extends \Worker { ``` protected $container ; public function __construct($container) { $this->container = $container; } public function run() { } ``` } class Configuration { ``` protected $type; public function __construct($type) { $this->type = $type; } public function getType() { return $this->type; } ``` } class ContainerThread extends \Thread { ``` protected $configuration; public function __construct($configuration) { $this->configuration = $configuration; } public function run() { $reflectionClass = new \ReflectionClass($this->configuration->getType()); $reflectionClass->newInstance(); } ``` } class Server { ``` protected $configurations = array(); public function loadConfiguration() { $this->configurations[] = new Configuration('SomeContainer'); } public function start() { $this->loadConfiguration(); foreach ($this->configurations as $configuration) { $thread = new ContainerThread($configuration); $thread->start(); } } ``` } $server = new Server(); $server->start(); ?>

Thanks for your attention.

Best regards
Tim

References not working

Code to reproduce:

class W1 {

    public function __construct() {                                                             
    }

}

class W2 {   
    public function __construct() {
    }       
}

class Message extends Stackable {

    public $message;

    public function run() {

    }

}

class T1  extends Thread {

    public function __construct( $message ) {                
        $this->message = $message;
    }

    public function run() {                 
    }
}

class T2 extends Thread {

    public $message;

    public function __construct( $message ) {

        $message->message = 'My message 1';

        $this->message = $message;
        $this->message->message = 'My message 2';

    }

    public function run() {

    }

}

$message = new Message();
$T1 = new T1( $message );
$T2 = new T2( $message );

var_dump( $message );

Expecting result is 'My message 2', but var_dump gives 'My message 1'

Unable to pass SplQueue on Thread

$arr = new SplQueue();
$arr[] = 'abc';

$arr2 = new TestArray;
$arr2->set($arr);

//class TestArray{
class TestArray extends Thread{
    private $arr;

    function set($arr){
        //
        // Not working as Thread
        //
        $this->arr = $arr;

        //
        // Printout to show
        //
        print_r($arr);
        print_r($this->arr);
    }

    function run(){
        return;
    }
}

Output as follow:-

SplQueue Object
(
    [flags:SplDoublyLinkedList:private] => 4
    [dllist:SplDoublyLinkedList:private] => Array
        (
            [0] => abc
        )

)
SplQueue Object
(
    [flags:SplDoublyLinkedList:private] => 4
    [dllist:SplDoublyLinkedList:private] => Array
        (
        )

)

How to install pthreads extension as a shared extension.

Hi I'm interested in how to use TSRM API correctly as I'm playing php-uv (libuv extension).
your project is very good reference about TSRM I've ever seen!

anyway, how to install this extension as a shared extension?
some unexported functions (e.g zend_activate ...) used in pthreads_object.h and shared extension can't resolve those.

on OSX.

dyld: lazy symbol binding failed: Symbol not found: _zend_activate
  Referenced from: /Users/chobie/src/pthreads/modules/pthreads.so
  Expected in: flat namespace

btw, I've tested with static extension and it seems good.

cd php-5.4.7
(cd ext && git clone git://github.com/krakjoe/pthreads.git)
./buildconf --force
# and add --enable-pthreads, --with-tsrm-pthreads and --enable-maintainer-zts options to ./configure and make install.

Thanks,

Removing segfaults if possible?

Can't you write some check in the php_var_serialisation_intern function which checks safely if a ressource can be copied or not. And if not write there a NULL-value. This would be useful when using a class which stores the mysqli-object (see #35 for example code) and I need for some reason to read data from the Db before starting the threads.

In this case it segfaults now. And as far I see the ressources are the only reason why it's segfaulting now...

Pass resources to a thread

I'm trying to create a socket server using pthreads in PHP and am trying to pass a socket to a thread to process it there. (the main thread keeps the listening socket, and spawns a thread per client connection).

Unfortunately the socket never gets there, but instead the variable just contains an integer 0.
The problem can also be reproduced with file handles. (example: https://gist.github.com/3907907)

I understand that this comes from the way variables are treated in the module (Serialize) but maybe there is a way to work around this somehow. Any ideas?

Windows Downloads are Missing

Windows downloads are missing, because GitHub removed the "Downloads" feature from their site. Please drop the missing files into a new Git repository so people can get a them.

Thread accessing static property causes segfault

When a thread tries to access a static property or class constant its segfaulting

<?php

class test extends Thread {
        static $test;
        function run() {
                echo date( DateTime::ISO8601 );
        }
}

$test = new test();
$test->start();
$test->join();
?>
(gdb) bt
#0  0x000000000092a434 in zend_update_class_constants (class_type=0x803161c40, tsrm_ls=0x802ffcaa0)
    at /usr/local/src/php-5.4.7/Zend/zend_API.c:1072
#1  0x000000000092a81d in _object_and_properties_init (arg=0x803163990, class_type=0x803161c40, properties=0x0,
    __zend_filename=0xeadc08 "/usr/local/src/php-5.4.7/ext/pthreads/src/object.c", __zend_lineno=631, tsrm_ls=0x802ffcaa0)
    at /usr/local/src/php-5.4.7/Zend/zend_API.c:1124
#2  0x000000000092a8ee in _object_init_ex (arg=0x803163990, class_type=0x803161c40,
    __zend_filename=0xeadc08 "/usr/local/src/php-5.4.7/ext/pthreads/src/object.c", __zend_lineno=631, tsrm_ls=0x802ffcaa0)
    at /usr/local/src/php-5.4.7/Zend/zend_API.c:1144
#3  0x00000000006aeccc in pthreads_routine (arg=0x802d15c80) at /usr/local/src/php-5.4.7/ext/pthreads/src/object.c:623
#4  0x00000008022a50a4 in pthread_getprio () from /lib/libthr.so.3
#5  0x0000000000000000 in ?? ()
Cannot access memory at address 0x7fffffbfe000

pthreads has detected an attempt to join with an unstarted

Thread member variable "data" is empty`in current git version. In version Commit 222add4 works fine.

 $directory = new Joxoo_System_Directory('/home/joxoo/Bilder/2012/08/07/');

        $starttime = microtime();

        $worker = new Joxoo_Thread_Worker();


        foreach ($directory as $file) {
            if ($file !== null) {
                $worker->stack('Joxoo_System_File', 'getMetaInformation', array(), array((string) $file));
            }
        }

        $worker->start();
        $worker->join();
        $end = microtime();
        printf($end - $starttime);
        $result = $worker->getDone();
class Joxoo_Thread extends Thread
{

     public function __prepare()
     {
         // Define path to application directory
         defined('APPLICATION_PATH')
         || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../application'));

         // Define application environment
         defined('APPLICATION_ENV')
         || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));

         // Ensure library/ is on include_path
         set_include_path(implode(PATH_SEPARATOR, array(
         realpath(APPLICATION_PATH . '/../library'),
         get_include_path(),
         )));

         /** Zend_Application */
         require_once 'Zend/Application.php';

         // Create application, bootstrap, and run
         $application = new Zend_Application(
                 APPLICATION_ENV,
                 APPLICATION_PATH . '/configs/application.ini'
         );
         $application->bootstrap();
     }

    public $data;
    /**
     * Constructor
     *
     * @param object $object
     * @param string $method
     * @param array $params
     * @param array $cparameters
     * @throws Joxoo_Exception_InvalidArgument
     */
    public function __construct()
    {
        $this->data = array();
        $this->done = array();
        $this->init = 0;
    }

    /**
     *
     */
    public function createWorkers(){
        $worker = 0;
        for(;$worker<count($this->data)-1;$worker++) {
            $this->stack($this);
            if (!$this->isStarted()) {
                $this->start();
            }
        }
    }

    /* (non-PHPdoc)
     * @see Thread::run()
     */
    public function run()
    {
        if (++$this->init) {
            printf("Work starts for %d/%d\n", $this->init, count($this->data));
               $this->done[$this->init-1] = $this->data[$this->init-1]->call();
        }

    }

    public function addWork($object)
    {
        $this->data[] = $object;
    }

    public function getDone()
    {
        return $this->done;
    }
}
class Joxoo_Thread_Worker
{
    /**
     * @var Joxoo_Thread
     */
    protected $worker;

    public function __construct()
    {
        $this->worker = new Joxoo_Thread();
    }

    /**
     * Stack new class object to worker
     *
     * @param string|Object $class
     * @param string $method
     * @param array $methodParams
     * @param array $classParams
     * @return number
     */
    public function stack($class, $method, array $methodParams = array(), array $classParams = array())
    {
        $object = new Joxoo_Thread_Object($class, $method, $methodParams, $classParams);
        return $this->stackThreadObject($object);
    }

    /**
     * Stack a new thread object to worker
     *
     * @param Joxoo_Thread_Object $object
     * @return number
     */
    public function stackThreadObject(Joxoo_Thread_Object $object)
    {
        return $this->worker->addWork($object);
    }

    /**
     * Start worker
     *
     * @param boolean $synchronized
     * @return boolean
     */
    public function start()
    {
        return $this->worker->createWorkers();
    }

    /**
     * Notify worker
     *
     * @return boolean
     */
    public function notify()
    {
        return $this->worker->notify();
    }

    /**
     * Set worker must wait
     *
     * @return boolean
     */
    public function wait($timeout = 0)
    {
        return $this->worker->wait($timeout);
    }
    /**
     * Check worker is joined
     *
     * @return boolean
     */
    public function isJoined()
    {
        return $this->worker->isJoined();
    }

    public function getDone()
    {
        return $this->worker->getDone();
    }

    /**
     * Get number of stacked threads
     *
     * @return boolean
     */
    public function getStacked()
    {
        return $this->worker->getStacked();
    }

    /**
     * Check worker is waiting
     *
     * @return boolean
     */
    public function isWaiting()
    {
        return $this->worker->isWaiting();
    }

    /**
     * Check worker is running
     *
     * @return boolean
     */
    public function isRunning()
    {
        return $this->worker->isRunning();
    }

    /**
     * Check worker is started
     *
     * @return boolean
     */
    public function isStarted()
    {
        return $this->worker->isStarted();
    }

    /**
     * Join worker
     *
     * return mixed
     */
    public function join()
    {
        return $this->worker->join();
    }
}

Magic Methods of Classes don't work

The Magic Methods are like completely overriden. Even unstatic methods like __get and __set don't work.

root# php static.php 
PHP Fatal error:  Call to undefined method Test::called_func() in /private/var/root/pth/tests/static.php on line 11

root# cat static.php 
<?php

class Test {
    public static function __callStatic ($name, $args) {
        var_dump($name, $args);
    }
}

class UserThread extends Thread {
    public function run () {
        Test::called_func("argument");
    }
}

$thread = new UserThread;
$thread->start();

if ($thread->isRunning())
    $thread->join();

Thread-ID Constant

I think there should be a better possibility to identify from a called external function the calling thread than passing every time the thread-instance an calling getThreadId. An use case would be a static sql-class (prenvents passing every time a mysqli-Object) which has one instance per thread.

Maybe simply by being able to make a difference between the threads by creating a constant like _FILE_ or _CLASS_.
So I think _THREAD_ should contain the Thread-id of current thread (zero if it's main-thread).

Or is this not even possible with the Zend API?

include_path is not inherited, with snippet

CLI mode,
module version: 0.38-rc,
php version: 5.4.4

#!/usr/local/php-5.4.4/bin/php
<?php

ini_set('include_path', '/var/www/library/');

class IncPath extends Thread
{

        public function run()
        {
                echo __CLASS__, ' ', ini_get('include_path'), "\n";
        }
}

echo 'Main thread', ' ', ini_get('include_path'), "\n";

$oThread = new IncPath;
$oThread->start();

Scores:

Main thread /var/www/library/
IncPath .:/usr/local/php-5.4.4/share/pear

Not compiling on windows

Unfortunately it seams the current version does not compile on windows with php 5.4.
Neither me nor my compiler seams to have any clue of what a "smart_str*" is surposed to be.

ext\pthreads\src\store.c(287) : warning C4113: 'apply_func_args_t' weicht in der Parameterliste von 'apply_func_t' ab
ext\pthreads\src\store.c(301) : error C2275: 'smart_str': Ungültige Verwendung dieses Typs als Ausdruck
        .\ext/standard/php_smart_str_public.h(30): Siehe Deklaration von 'smart_str'
ext\pthreads\src\store.c(301) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(302) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(306) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(306) : warning C4047: 'Funktion': Anzahl der Dereferenzierungen bei 'smart_str *' und 'int' unterschiedlich
ext\pthreads\src\store.c(306) : warning C4024: 'php_var_serialize': Unterschiedliche Typen für formalen und übergebenen Parameter 1
ext\pthreads\src\store.c(312) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(312) : error C2223: Der linke Teil von '->len' muss auf eine Struktur/Union zeigen
ext\pthreads\src\store.c(313) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(313) : error C2223: Der linke Teil von '->len' muss auf eine Struktur/Union zeigen
ext\pthreads\src\store.c(314) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(314) : error C2223: Der linke Teil von '->len' muss auf eine Struktur/Union zeigen
ext\pthreads\src\store.c(314) : error C2198: "calloc": Nicht genügend Argumente für Aufruf.
ext\pthreads\src\store.c(317) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(317) : error C2223: Der linke Teil von '->c' muss auf eine Struktur/Union zeigen
ext\pthreads\src\store.c(317) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(317) : error C2223: Der linke Teil von '->len' muss auf eine Struktur/Union zeigen
ext\pthreads\src\store.c(318) : error C2198: "memmove": Nicht genügend Argumente für Aufruf.
ext\pthreads\src\store.c(322) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(323) : error C2065: 'psmart': nichtdeklarierter Bezeichner
ext\pthreads\src\store.c(323) : warning C4022: 'free': Zeigertyp für übergebenen Parameter 1 stimmt nicht mit dem deklarierten Zeigertyp überein

Seams to be a problem that came in in 6aa99d4. VC doesn't seam to like function calls before a variable definitiv. Move the calloc (line 301) before line 298 fixes the problem.

Bug Static member

access to static property directly works. But not inside method.

Ex:

class MyThread {
public static $instance;
public static function get() {echo '-';
if (!self::$instance)
self::$instance = new self;
return self::$instance;
}
}

MyThread::get();
echo var_dump($MyThread::$instance);

class Test extends Thread {
public function run() {

    // Error
    MyThread::get();
    echo var_dump($MyThread::$instance);

            // Works
            MyThread::$instance = new MyThread();
           echo var_dump($MyThread::$instance);
}

}

$Test = new Test();
$Test->start();
$Test->join();

Not a valid WIN32 Application

I just dowloaded the pthreads-0.36-php-5.3 from the downloads section. I copied out the php_pthreads.dll and put it in my PHP extensions folder and also copied pthreadVC2.dll and put it in the PHP root folder as suggested in one of the issues posted on here. When I try to start apache however, I get this error:

PHP Warning: PHP Startup: Unable to load dynamic library 'c:/wamp/bin/php/php5.3.8/ext/php_pthreads.dll' - %1 is not a valid Win32 application.\r\n in Unknown on line 0

What could be the problem please. Thanks in advance.

PHP Segmentation fault at start

Some users are notifyng me that PHP 5.4.11 crashes before executing any code, happening on Windows, and to only one on Linux.

I don't have any more details though, because these users only tweeted me. I talked with one of them to check if my code was executed, but a simple "echo 1;" failed. Also tested disabling the pthreads extension on Windows, and the code executed.

Thanks!

die() / exit() /exceptions / fatal errors only aborting the current thread

<?php

class test1 extends Thread {
        function run() {
                for($i = 0; $i < 100; $i++) {
                        echo "x:".$i."\n";
                        usleep(100000);
                }
        }
}

class test2 extends Thread {
        function run() {
                $test = new Exception();
                throw $test;
        }
}

$test1 = new test1();
$test1->start();
$test2 = new test2();
$test2->start();

$test1->join();
$test2->join();

normally I'd expect a die() / exit() or an uncougth exception to terminate program execution and not just the current thread. You can replace the throw in the above example with a die() or exit().

Even though I'm not quite sure if this is something that can even be fixed in the scope of the module I thought I'd report it. Maybe somebody got an idea to get this working cleanly.

Shutdown Worker's and Thread's

Hi Joe,

thanks for your answer to our shutdown problem yesterday. You're right i've made a mistake in the worker by implement a while loop in the run method.

But today we faced a problem that seems to be a bit more complicated. As you can see in the example we're working on a socket server that is able to start a several number of socket servers, each of the socket server can start one or more workers to serve the requests.

As we need a controlled shutdown process when pressing CTRL-C we're trying to implement a PCNTL based signal handler to catch the signal and shutdown the threads and the workers. Everything seems to work fine, but when one of the workers serve's a request a second time the daemons wrapping thread won't stop working. If all workers serve's only one request the shutdown method works as expected. To fire a test request against the server you can use telnet with 'telnet 127.0.0.1 8585'.

You can find a working example below. To start the example you need the APC and the PCNTL extension compiled:

client = $client; } public function run() { if ($this->worker) { $client = $this->client; // initialize the buffer $buffer = ''; // set the new line character $newLine = $this->newLine; // read a chunk from the socket while ($buffer .= socket_read($client, $this->lineLength, PHP_BINARY_READ)) { // check if a new line character was found if (substr($buffer, -1) === $newLine) { // if yes, trim and return the data return rtrim($buffer, $newLine); } } error_log(__METHOD__ . ':' . __LINE__); $response = array(); socket_write($client, serialize($response) . "\n"); socket_close($client); } } ``` } class TestReceiver { ``` protected $work; protected $workers; public function __construct($container) { $this->container = $container; $this->work = array(); $this->workers = array(); } public function start() { $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_bind($socket, '127.0.0.1', 8585); socket_listen($socket); socket_set_nonblock($socket); while (true) { try { if (apc_exists('system_shutdown') && apc_fetch('system_shutdown') === true) { break; } if ($client = @socket_accept($socket)) { $request = new TestRequest($client); $worker = $this->getRandomWorker(); $worker->stack($this->work[] = $request); } } catch(\Exception $e) { error_log($e->__toString()); } usleep(300); } socket_close($socket); $socket = array(); $this->shutdown(); } public function shutdown() { error_log("Found " . ($work = sizeof($this->work)) . " work"); $this->work = array(); error_log("Found " . ($workers = sizeof($this->workers)) . " workers"); foreach ($this->workers as $worker) { $worker->shutdown(); } $this->workers = array(); error_log("Successfully shutdown $workers worker"); } public function getRandomWorker() { $i = rand(0, 3); if (array_key_exists($i, $this->workers) === false) { $worker = new TestWorker(); $worker->start(); $this->workers[$i] = $worker; } return $this->workers[$i]; } ``` } class TestContainer { ``` protected $receiver; public function start() { $this->receiver = new TestReceiver($this); $this->receiver->start(); } ``` } class TestThread extends \Thread { ``` protected $container; public function run() { $this->container = new TestContainer(); $this->container->start(); $this->notify(); } ``` } class Server { ``` protected $threads = array(); public function start() { for ($i = 0; $i < 1; $i++) { $this->threads[$i] = new TestThread(); $this->threads[$i]->start(); } while (true) { sleep(1); } } public function __construct() { // catch fatal error (rollback) register_shutdown_function(array($this, 'fatalErrorShutdown')); // catch Ctrl+C, kill and SIGTERM (rollback) pcntl_signal(SIGTERM, array($this, 'sigintShutdown')); pcntl_signal(SIGINT, array($this, 'sigintShutdown')); apc_store('system_shutdown', false); } public function shutdown() { apc_store('system_shutdown', true); sleep(1); for ($i = 0; $i < 1; $i++) { error_log("Now try to shutdown thread " . $this->threads[$i]->getThreadId()); $this->threads[$i]->join(); error_log("Successfully shutdown thread " . $this->threads[$i]->getThreadId()); } die ("System shutdown complete\n"); } public function fatalErrorShutdown() { $lastError = error_get_last(); if (!is_null($lastError) && $lastError['type'] === E_ERROR) { $this->shutdown(); } } public function sigintShutdown($signal) { if ($signal === SIGINT || $signal === SIGTERM) { $this->shutdown(); } } ``` } $server = new Server(); $server->start(); ?>

Thanks for your time Joe ...

Best regards
Tim

Running threads in global scope

Since a while I am working on an HTTP server ( http://pancakehttp.net ) written in PHP. Currently, I use forking in order create multiple "threads". I always wanted to have pthreads, which would now be possible with your extension, but there is one problem for me: I can't have threads run code in global scope.
My server has its own PHP SAPI written in PHP. In order to execute third party scripts, I need to have the workers running in global scope as most PHP web applications won't run properly in a functions or methods scope. I don't know whether this is easily possible, but it would be really nice if you could try implementing such a feature. In particular, it would be great if the thread could just load and run a specified PHP file in global scope when started.

Mutex::lock will block all threads?

class a extends Thread
{
    private static $a = 0;
    private static $mutex;
    public static function __init__()
    {
        self::$mutex = Mutex::create(true);
    }


    public function run()
    {
        sleep(2);
        Mutex::lock(self::$mutex);
        self::$a++;
        echo self::$a;
        Mutex::unlock(self::$mutex);
    }
}

a::__init__();
$arr = array();
for ($i=0;$i<=500;$i++) {
    $arr[$i] = new a();
    $arr[$i]->start();
    //echo $arr[$i]->getThreadId() . "\n";
}

hello , i wrote this code, and it seems don not work.
no result , no exit, all threads block

Can't shutdown worker

Hi Joe,

as we're working on a socket server that handles request in some case we faced the problem that we can't implement a controlled shutdown initiated with CTRL-C as the worker can't be shutdown.

The example is really simple and i think this should work:

workers[$i] = new TestWorker(); $this->workers[$i]->start(); error_log("Successfully started worker " . $this->workers[$i]->getThreadId()); } while (true) { sleep(1); } } public function __construct() { // catch fatal error (rollback) register_shutdown_function(array($this, 'fatalErrorShutdown')); // catch Ctrl+C, kill and SIGTERM (rollback) pcntl_signal(SIGTERM, array($this, 'sigintShutdown')); pcntl_signal(SIGINT, array($this, 'sigintShutdown')); } public function shutdown() { for ($i = 0; $i < sizeof($this->workers); $i++) { error_log("Now try to shutdown thread " . $this->workers[$i]->getThreadId()); $this->workers[$i]->shutdown(); error_log("Successfully shutdown thread " . $this->workers[$i]->getThreadId()); } exit; } /** * Method that is executed, when a fatal error occurs. * * @return void */ public function fatalErrorShutdown() { error_log(__METHOD__ . ':' . __LINE__); $lastError = error_get_last(); if (!is_null($lastError) && $lastError['type'] === E_ERROR) { $this->shutdown(); } } /** * Method, that is executed, if script has been killed by: * * SIGINT: Ctrl+C * SIGTERM: kill * * @param int $signal */ public function sigintShutdown($signal) { error_log(__METHOD__ . ':' . __LINE__); if ($signal === SIGINT || $signal === SIGTERM) { $this->shutdown(); } } ``` } $server = new Server(); $server->start(); ?>

Thanks for your attention :)

Best regards
Tim

$timeout on wait() may not work

Notice the following code may wait() indefinitely even with $timeout argument.

class Test extends Thread{
    public function run(){
        $this->wait(1000000); // Wait and timeout in 1 sec
    }
}

$test = new Test;
$test->start();
usleep(500000); // Sleep 0.5 sec
//$test->notify(); Will wait() timeout without notify()?
$test->join();

print "Done\n";

Worker thoesn't return the stacked Thread result

I use pthreads with Zend Framework and extends there.

Code:

The Abstract Class

abstract class Joxoo_Thread_ThreadAbstract extends Thread
{
    public function __prepare()
    {
        defined('APPLICATION_PATH')
        || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../../application'));

        // Define application environment
        defined('APPLICATION_ENV')
        || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

        // Ensure library/ is on include_path
        set_include_path(implode(PATH_SEPARATOR, array(
        realpath(dirname(__FILE__) . '/../../'),
        get_include_path(),
        )));

        /** Zend_Application */
        require_once 'Zend/Application.php';

        // Create application, bootstrap, and run
        $application = new Zend_Application(
                APPLICATION_ENV,
                APPLICATION_PATH . '/configs/application.ini'
        );
        $application->bootstrap();
        return true;
    }
}

The thread class

class Joxoo_Thread extends Joxoo_Thread_Worker
{

    /**
     * Constructor
     *
     * @param object $object
     * @param string $method
     * @param array $params
     * @param array $cparameters
     * @throws Joxoo_Exception_InvalidArgument
     */
    public function __construct(
        $object = null, $method = null, array $params = array(), array $cparameters = array())
    {
        if ($object === null) {
            return;
        }

        if (is_object($object) && !method_exists($object, $method)) {
            throw new Joxoo_Exception_InvalidArgument('Object is not a object or method does not exists in object');
        }

        $this->object = new Joxoo_Thread_Object($object, $cparameters);
        $this->method = $method;
        $this->params = $params;
    }

    /* (non-PHPdoc)
     * @see Thread::run()
     */
    public function run()
    {
        $result = $this->object->call($this->method, $this->params);
        Zend_Registry::get('SYSTEM_LOGGER')->log($result , 6);
        return $result;
    }

}

The Worker class

class Joxoo_Thread_Worker extends Joxoo_Thread_ThreadAbstract
{
    /**
     * Constructor
     *
     * @param Mutex $mutex
     */
    public function __construct(Mutex $mutex = null)
    {
        $this->mutex = $mutex;
    }

    /* (non-PHPdoc)
     * @see Thread::run()
     */
    public function run()
    {
        if ($this->mutex !== null) {
            $locked = Mutex::lock($this->mutex);

        }

        Zend_Registry::get('SYSTEM_LOGGER')->log(
            printf("%s#%lu:<-", isset($locked)?"Y":"N", $this->getThreadId()), 6);

        while (!$this->isWaiting()) {
            if ($this->mutex !== null) {
                Mutex::unlock($this->mutex);
            }
        }
        return true;
    }
}

The Thread Object

final class Joxoo_Thread_Object
{
    public $class;

    public $cparameter;

    /**
     * Constructor
     *
     * @param string $class
     * @param array $parameters
     */
    public function __construct($class, array $parameters = array())
    {
        if (!is_object($class)) {
            $this->class = (string) $class;
            $this->cparameter = $parameters;
            return;
        }

        $this->class = get_class($class);

        $reflection = new ReflectionClass($class);

        $properties = $reflection->getProperties();

        $constructor = $reflection->getConstructor();

        $params = $constructor->getParameters();
        foreach ($params as $param) {
            $name = $param->getName();
            $this->cparameter[] = $this->_getConstructerValues($properties, $name, $class);
        }
    }

    /**
     * Call method
     *
     * @param string $method
     * @param array $params
     * @return mixed
     */
    public function call($method, array $params = array())
    {
        $reflection = new ReflectionClass($this->class);
        $instance = $reflection->newInstanceArgs($this->cparameter);
        Zend_Registry::get('SYSTEM_LOGGER')->log($method , 6);
        return $instance->$method($params);
    }

    private function _getConstructerValues(array $properties, $name, $class)
    {
        if (!is_object($class)) {
            return '';
        }
        foreach ($properties as $property) {
            $property->setAccessible(true);

            $pname = $property->getName();
            if ($pname === $name || $pname === '_' . $name) {
                return (string) $property->getValue($class);
            }
        }
        return '';
    }
}

The call

public function testReadImages()
    {
        $directory = new Joxoo_System_Directory('/home/joxoo/Bilder/2012/08/07/');

        $worker = new Joxoo_Thread_Worker();
        $worker->start();

        foreach ($directory as $file) {
            if ($file !== null) {
                $worker->stack(
                    new Joxoo_Thread('Joxoo_System_File', 'getMetaInformation', array(), array((string) $file)));
            }
        }
        var_dump($worker->join());
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.