1、linux下的php多线程
下面所讲的东西是源自php的pcntl_fork函数.因为这个函数依赖操作系统fork的实现,所以本文所讲的东西只适用于linux/unix。那么先看看这个函数的用法吧.php手册上是这么说的:
1
2
3
4
5
6
7
8
|
<?php
$pid = pcntl_fork(); if ( $pid == -1) {
die ( 'could not fork' );
} else if ( $pid ) {
pcntl_wait( $status ); /
/Protect against Zombie children} else {
|
通过pcntl_fork创建一个子进程,如果返回值是-1的话,那么说明子进程创建失败.创建成功的进程id会返回给父进程,0返回给子进程.不好理解吧,所以应该这样写:
1
2
3
4
5
6
7
8
9
|
<?php
$pid = pcntl_fork(); if ( $pid == -1){
die ( 'could not fork' );
} else { if ( $pid ){
exit (0);
} else {
exit (0);
}
}?>
|
这样一改好理解多了,如果你父进程希望知道子进程正常退出的话,可以加上前面的pcntl_wait。
2.通过stream_socket_client 方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
function sendStream() {
$english_format_number = number_format( $number , 4, '.' , '' );
echo $english_format_number ;
exit ();
$timeout = 10;
$result = array ();
$sockets = array ();
$convenient_read_block = 8192;
$host = "test.local.com" ;
$sql = "select waybill_id,order_id from xm_waybill where status>40 order by update_time desc limit 1 " ;
$data = Yii::app()->db->createCommand( $sql )->queryAll();
$id = 0;
foreach ( $data as $k => $v ) {
if ( $k % 2 == 0) {
$send_data [ $k ][ 'body' ] = NoticeOrder::getSendData( $v [ 'waybill_id' ]);
} else {
$send_data [ $k ][ 'body' ] = array ( $v [ 'order_id' ] => array ( 'extra' => 16));
}
$data = json_encode( $send_data [ $k ][ 'body' ]);
$s = stream_socket_client( $host . ":80" , $errno , $errstr , $timeout , STREAM_CLIENT_ASYNC_CONNECT | STREAM_CLIENT_CONNECT);
if ( $s ) {
$sockets [ $id ++] = $s ;
$http_message = "GET /php/test.php?data=" . $data . " HTTP/1.0\r\nHost:" . $host . "\r\n\r\n" ;
fwrite( $s , $http_message );
} else {
echo "Stream " . $id . " failed to open correctly." ;
}
}
while ( count ( $sockets )) {
$read = $sockets ;
stream_select( $read , $w = null, $e = null, $timeout );
if ( count ( $read )) {
foreach ( $read as $r ) {
$id = array_search ( $r , $sockets );
$data = fread ( $r , $convenient_read_block );
if ( strlen ( $data ) == 0) {
echo "Stream " . $id . " closes at " . date ( 'h:i:s' ) . ".<br> " ;
fclose( $r );
unset( $sockets [ $id ]);
} else {
$result [ $id ] = $data ;
}
}
} else {
echo "Time-out!\n" ;
break ;
}
}
print_r( $result );
}
|
3、通过多进程代替多线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
function daemon( $func_name , $args , $number ){
while (true){
$pid =pcntl_fork();
if ( $pid ==-1){
echo "fork process fail" ;
exit ();
} elseif ( $pid ){
static $num =0;
$num ++;
if ( $num >= $number ){
pcntl_wait( $status );
$num --;
}
} else {
if (function_exists( $func_name )){
while (true) {
$ppid =posix_getpid();
var_dump( $ppid );
call_user_func_array( $func_name , $args );
sleep(2);
}
} else {
echo "function is not exists" ;
}
exit ();
}
}
} function worker( $args ){
}
daemon( 'worker' , array (1),2);
|
来源:https://www.php.cn/php-weizijiaocheng-381235.html