util.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 2018/7/28
  6. * Time: 下午12:49
  7. */
  8. namespace event;
  9. use Log;
  10. class util
  11. {
  12. static public function listen($host,$port)
  13. {
  14. $listen_fd = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  15. if(!socket_set_option($listen_fd, SOL_SOCKET, SO_REUSEADDR, 1)) {
  16. Log::record("socket_set_option 地址重用失败.",Log::DEBUG);
  17. return false;
  18. }
  19. if(!socket_set_nonblock($listen_fd)) {
  20. $err = socket_last_error();
  21. Log::record("socket_set_blocking error : {$err}",Log::DEBUG);
  22. return false;
  23. }
  24. if(!socket_bind($listen_fd, $host, $port)) {
  25. echo "无法绑定socket {$host} : {$port},请退出之前进程.\n";
  26. return false;
  27. }
  28. if(!socket_listen($listen_fd)) {
  29. echo "无法监听socket,请退出之前进程.\n";
  30. return false;
  31. }
  32. return $listen_fd;
  33. }
  34. static public function listen_block($host,$port)
  35. {
  36. $listen_fd = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  37. if(!socket_set_option($listen_fd, SOL_SOCKET, SO_REUSEADDR, 1)) {
  38. Log::record("socket_set_option 地址重用失败.",Log::DEBUG);
  39. return false;
  40. }
  41. if(!socket_bind($listen_fd, $host, $port)) {
  42. echo "无法绑定socket {$host} : {$port},请退出之前进程.\n";
  43. return false;
  44. }
  45. if(!socket_listen($listen_fd)) {
  46. echo "无法监听socket,请退出之前进程.\n";
  47. return false;
  48. }
  49. return $listen_fd;
  50. }
  51. static function fork_child($callback, $params)
  52. {
  53. if (($pid = pcntl_fork()) === 0)
  54. {
  55. //ob_end_clean(); // Discard the output buffer and close
  56. fclose(STDIN); // Close all of the standard
  57. fclose(STDOUT); // file descriptors as we
  58. fclose(STDERR); // are running as a daemon.
  59. Log::record("pcntl_fork pid = {$pid}",Log::DEBUG);
  60. if(!empty($params)) {
  61. call_user_func_array($callback,$params);
  62. } else {
  63. call_user_func($callback);
  64. }
  65. exit();
  66. }
  67. elseif($pid === -1)
  68. {
  69. Log::record("pid = {$pid},could not fork process",Log::DEBUG);
  70. die('could not fork process');
  71. }
  72. else
  73. {
  74. $ret = pcntl_waitpid($pid,$status,WNOHANG);
  75. Log::record("pcntl_waitpid pid = {$pid},ret={$ret}",Log::DEBUG);
  76. if($ret == 0) {
  77. Log::record("fork_child: successful ret == 0 PID: {$pid}",Log::DEBUG);
  78. return $pid;
  79. }
  80. elseif($ret == -1) {
  81. Log::record("fork_child: ret == -1 PID: {$pid}",Log::DEBUG);
  82. }
  83. else {
  84. Log::record("fork_child: ret == 0 child exited PID: {$pid}.",Log::DEBUG);
  85. }
  86. }
  87. }
  88. static function fork_listen($fd, $callback, $count)
  89. {
  90. $params = [$fd];
  91. $count = intval($count);
  92. if($count <= 0) {
  93. return call_user_func_array($callback,$params);
  94. }
  95. else
  96. {
  97. $childs = [];
  98. while ($count--) {
  99. $childs[] = util::fork_child($callback,$params);
  100. }
  101. }
  102. return $childs;
  103. }
  104. static function fork_listenex($fd, $callback, $count)
  105. {
  106. self::fork_listen($fd,$callback,$count);
  107. while ($count) {
  108. Log::record("waitting child quit......",Log::DEBUG);
  109. $ret = pcntl_wait($status);
  110. Log::record("pcntl_waitpid ret={$ret}",Log::DEBUG);
  111. if($ret > 0)
  112. {
  113. if(pcntl_wifexited($status)) {
  114. $ret = pcntl_wexitstatus($status);
  115. Log::record("child normal quit ret={$ret} status = {$status}",Log::DEBUG);
  116. } else {
  117. $ret = pcntl_wexitstatus($status);
  118. Log::record("child abnormal quit ret={$ret} status = {$status}",Log::DEBUG);
  119. }
  120. self::fork_listen($fd,$callback,1);
  121. }
  122. else {
  123. //子进程已经退出干净了.
  124. break;
  125. }
  126. }
  127. }
  128. static function join()
  129. {
  130. do {
  131. Log::record("waitting child quit......",Log::DEBUG);
  132. $ret = pcntl_wait($status);
  133. Log::record("pcntl_waitpid ret={$ret}",Log::DEBUG);
  134. if($ret > 0)
  135. {
  136. if(pcntl_wifexited($status)) {
  137. $ret = pcntl_wexitstatus($status);
  138. Log::record("child normal quit ret={$ret} status = {$status}",Log::DEBUG);
  139. } else {
  140. $ret = pcntl_wexitstatus($status);
  141. Log::record("child abnormal quit ret={$ret} status = {$status}",Log::DEBUG);
  142. }
  143. }
  144. else {
  145. //子进程已经退出干净了.
  146. break;
  147. }
  148. }
  149. while(true);
  150. }
  151. static function fork_worker($callback, $count)
  152. {
  153. $count = intval($count);
  154. if($count <= 0) {
  155. return call_user_func($callback);
  156. }
  157. else
  158. {
  159. while ($count--) {
  160. util::fork_child($callback,NULL);
  161. }
  162. }
  163. }
  164. static function fork_workerex($callback, $count)
  165. {
  166. self::fork_worker($callback,$count);
  167. while ($count) {
  168. Log::record("waitting child quit......",Log::DEBUG);
  169. $ret = pcntl_wait($status);
  170. Log::record("pcntl_waitpid ret={$ret}",Log::DEBUG);
  171. if($ret > 0)
  172. {
  173. if(pcntl_wifexited($status)) {
  174. $ret = pcntl_wexitstatus($status);
  175. Log::record("child normal quit ret={$ret} status = {$status}",Log::DEBUG);
  176. } else {
  177. $ret = pcntl_wexitstatus($status);
  178. Log::record("child abnormal quit ret={$ret} status = {$status}",Log::DEBUG);
  179. }
  180. self::fork_worker($callback,1);
  181. }
  182. else {
  183. //子进程已经退出干净了.
  184. break;
  185. }
  186. }
  187. }
  188. }