php 模擬多線程

一、linux下的php多線程php

下面所講的東西是源自php的pcntl_fork函數.由於這個函數依賴操做系統fork的實現,因此本文所講的東西只適用於linux/unix。那麼先看看這個函數的用法吧.php手冊上是這麼說的:html

1linux

2sql

3json

4多線程

5app

6socket

7函數

8spa

<?php

$pid = pcntl_fork();if ($pid == -1) {        

die('could not fork');

} else if ($pid) {        

// we are the parent

         pcntl_wait($status); /

/Protect against Zombie children} else {        

// we are the child}?>

經過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)) { 

        /* stream_select generally shuffles $read, so we need to

         compute from which socket(s) we're reading. */

        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

        /* A time-out means that *all* streams have failed

         to receive a response. */

        echo "Time-out!\n";

        break;

      

    

    print_r($result);

   

  }

三、經過多進程代替多線程

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{ //爲0 則表明是子進程建立的,則直接進入工做狀態

   

      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){ 

  //do something

  

daemon('worker',array(1),2);

 

來源:https://www.php.cn/php-weizijiaocheng-381235.html

相關文章
相關標籤/搜索