Jump to content

Recommended Posts

Have you tried adding PHP to your Google search string? ;)

 

I've searched my history and bookmarks, but apparently it's been too long since I found whatever it was I learned from. And I didn't bookmark it. I do have a project running using pcntl_* functions.

 

Prepare to write more code ;)

 

Here's the heart of a multi-threaded "fetcher" that uses posix_getpid, pcntl_fork and pcntl_waitpid in conjunction with an external function I didn't show (systemFetchSequential(), uses fetch/wget to get urls and write them to $outpath).

 

The function is_pid() simply returns false if the PID isn't set (probably could just use a truth check and is_int(), but I didn't and can't remember why). threaded_fetch() is limited to 10 threads by the huge if/elseif construct there; if you write more code you can have more threads. I can't recall the reason, but a switch wouldn't work according to the guy I was reading.

 

function is_pid($n) { return ($n > 0); } //EOF

function threaded_fetch( $url_array, $outpath ) {

global $threads; //we get this from the calling environment

if ( $threads > 10 ) die("Threaded_fetch() function cannot support more than 10 threads.");

$url_chunks = array_chunk( $url_array, (ceil((count($url_array)) / $threads ))+5, true );

/* PNCTL_FORK() implementation */

$ppid=posix_getpid(); // Keep reference to the PID of the parent process
$pids=array( range( 0,( $threads ) ) ); // An array to hold refrence to PIDs of child processes

for ( $i = 0; $i<=$threads; $i++ ) {

$pid=pcntl_fork(); // Forks a new child process and keeps refrence to its PID;
if ( $pid == -1 ) {
die( 'could not fork' );
}
if ( !$pid ) { /* This only runs in a child process */
$pids[$i] = posix_getpid();// Get the PID of the child process
break;
} else {
$pids[$i] = $pid;
}
} //for $i

$active_pids = count(array_filter($pids,"is_pid"));
print("Started $active_pids children to process ".count($url_chunks)." chunks of data.");

/* By this time all processes, child and parent have their own copy of $pid and $pids[]*/

$current_pid=posix_getpid(); // Get the PID of the curently running process

if ( $current_pid == $pids[0] ) { /* Task for child 1 */
systemFetchSequential( $url_chunks[0],"$outpath" );
exit();
} elseif ( $current_pid == $pids[1] ) { /* Task for child 2 */
systemFetchSequential( $url_chunks[1],"$outpath" );
exit();
} elseif ( $current_pid == $pids[2] ) { /* Task for child 3 */
systemFetchSequential($subpage_chunks[2],"$outpath");
exit();
} elseif ( $current_pid == $pids[3] ) { /* Task for child 4 */
systemFetchSequential( $url_chunks[3],"$outpath" );
exit();
} elseif ( $current_pid == $pids[4] ) { /* Task for child 5 */
systemFetchSequential( $url_chunks[4],"$outpath" );
exit();
} elseif ( $current_pid == $pids[5] ) { /* Task for child 6 */
systemFetchSequential( $url_chunks[5],"$outpath" );
exit();
} elseif ( $current_pid == $pids[6] ) { /* Task for child 7 */
systemFetchSequential( $url_chunks[6],"$outpath" );
exit();
} elseif ( $current_pid == $pids[7] ) { /* Task for child 8 */
systemFetchSequential( $url_chunks[7],"$outpath" );
exit();
} elseif ( $current_pid == $pids[8] ) { /* Task for child 9 */
systemFetchSequential( $url_chunks[8],"$outpath" );
exit();
} elseif ( $current_pid == $pids[9] ) { /* Task for child 10 */
systemFetchSequential( $url_chunks[9],"$outpath" );
exit();
}

foreach ( $pids as $key => $val ) { //wait/exit routine
pcntl_waitpid( $val, $status );
unset( $pids[$key] );
}
} //EOF

 

In this case, running this function with a $url_array will start 10 children on the server, running fetch/wget against a chunk of the $url_array until they're done.

Edited by dalecosp

Thanks for attempting to help, but ....

 

let me try and explain my question a bit more clearly.

I am looking to learn pThreads as described here: https://gist.github.com/krakjoe/6437782

The above article talks a lot about synchronization / mutex / waiting / sharing / context and other unknown concepts.. These are the concepts and generally learning pthreads is the help I am looking for.

Taking a real world example:

class WebRequest extends Thread {
    public function run() {
       for_doc() ;
       echo 'Running Thread : ' . $this->getCurrentThreadId() ."\n";
    }
}

Here the for_doc() is a factory function that creates a Object of type A class, but all calls to $this return null ( I know I didn't explain the issue well, ut I am just trying to give an idea about what confuses me about multithreading)

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.