PHPCLI multi-process execution startup script-PHP source code

Source: Internet
Author: User
Tags php cli usleep
PHPCLI multi-process execution startup script 1.

2. bat. php

#! /Usr/bin/env php
 159);} function B ($ line) {do {bat: Y ("I am passing the parameter \ $ line = $ line"); usleep (500000 );} while (mt_rand (100,999)> 359);} function c () {global $ x; bat: notify ("The initial variable values between multiple tasks are not affected, \ $ x = $ x "); bat: notify (" I'm suspending the 9-second test "); sleep (9); bat :: Y ("I'm an error code 5 test"); exit (5);} *?> * // ** Make sure that this script can only run in SHELL */if (substr (php_sapi_name (), 0, 3 )! = 'Cli ') {die ("This Programe can only be run in cli mode. \ n");} if (! Is_callable ('pcntl _ fork') |! Is_callable ('MSG _ send') {bat: message ("this program requires pcntl, sysvmsg extension, but your system is not installed! ", 2); exit (5);} class bat {static private $ max = 3, $ total = 0, $ running = 0, $ failure = 0, $ finished = 0, $ tasks = array (), $ msg, $ msgs = array (), $ logfile = "/tmp/bat. php. log ", $ childs, $ get, $ parent, $ start, $ split; static function main () {$ I = 1; $ files = array (); if ($ _ SERVER ["argc"]> 1) {while ($ I <$ _ SERVER ["argc"]) {switch ($ _ SERVER ["argv"] [$ I ++]) {case "? ": Case "/? ": Case "-? ": Case"-h ": case" -- help ": self: usage (); case"-f ": case" -- file ": $ file = $ _ SERVER ["argv"] [$ I ++]; if (is_readable ($ file) {$ files [] = $ file; continue ;} if (is_null ($ file) {self: message ("script parameter missing", 1); help (1) ;}else {self :: message ("script $ file is not in or inaccessible", 2); exit (4);} case "-m": case "-- max": if (self :: $ max = $ _ SERVER ["argv"] [$ I ++]) {self ::$ max = intval (self ::$ max); if (self :: $ max> = 1) {continue ;} Self: message ("number of processes should be a positive integer", 2); exit (8) ;}self: message ("number of unspecified processes", 2 ); exit (7); case "-l": case "-- log": case "-- logfile": if (self :: $ logfile = $ _ SERVER ["argv"] [$ I ++]) {if (is_dir (self ::$ logfile) {self ::$ logfile. = "/bat. php. log ";} if (is_file (self ::$ logfile) {if (is_writable (self ::$ logfile) {continue ;}} else {if (is_writable (dirname (self: $ logfile) {continue;} self: message ("log directory cannot be written", 2); e Xit (9);} case "-v": case "-- version": exit (self: version (); default: $ file = $ _ SERVER ["argv"] [$ I-1]; if (is_readable ($ file) {$ files [] = $ file; continue;} self:: message ("The script $ file is not in or cannot be accessed", 2); exit (4) ;}} set_time_limit (0); error_reporting (8106 & E_ALL ); ini_set ('display _ errors ', 'off'); set_error_handler (array (_ CLASS __, 'error'), E_ALL); set_exception_handler (array (_ CLASS __, 'exception ') ); Register_shutdown_function (array (_ CLASS __, 'shutdown '); self: $ start = time (); self: $ split = str_repeat (' = ', 512); self ::$ parent = msg_get_queue (getmypid (); foreach ($ files as $ file) {self: inc ($ file);} self :: end (); exit;} self: usage ();} static function run ($ fun, $ arg = null) {if (is_callable ($ fun) {self :: $ tasks [] = array ($ fun, $ arg);} else {throw new Exception ("not a function or cannot be called", 9);} stati C function start () {self ::$ total = count (self ::$ tasks); foreach (self ::$ tasks as $ fun_arg) {if (self :: $ max <++ self ::$ running) {self: run_wait ();} elseif (self: $ running = 1) {# clear the screen and set the cursor to the first line $ x = intval ('tput Lines'); echo str_repeat ("\ n", $ x-1); self :: flush ('Program starts to execute... ', 1) ;}if ($ cid = pcntl_fork () {if ($ cid <0) {throw new Exception ("process creation failed", 3);} self:: $ childs [$ cid] = msg_get_queue ($ cid);} else {Ob_start (); self ::$ tasks = array (); self ::$ get = msg_get_queue (getmypid (); self :: $ msg = sprintf ("%-6d", getmypid (); msg_send (self: $ parent, 1, getmypid (), false ); call_user_func ($ fun_arg [0], $ fun_arg [1]); exit ;}} while (self ::$ running) self: run_wait (); self :: $ tasks = array ();} static private function run_wait () {$ nomsg_interval = time (); label_wait: if (msg_receive (self: $ parent, 0, $ typ, 8192, $ Msg, false, MSG_NOERROR | MSG_IPC_NOWAIT) {if ($ typ! = 3) {if ($ typ = 1) {$ msg = sprintf ("%-6d % s", $ msg, date ("H: I: s "), 'process start');} elseif ($ typ = 4) {label_child_exit: unset (self ::$ childs [pcntl_waitpid ($ msg, & $ status)]); if (! Pcntl_wifexited ($ status) | pcntl_wexitstatus ($ status) {$ msg = sprintf ("%-6d % s", $ msg, date ("H: I: s "), 'process exits abnormally '); if (pcntl_wifexited ($ status) {$ msg. = ', error code :'. pcntl_wexitstatus ($ status);} self: $ failure ++;} else {$ msg = sprintf ("%-6d % s", $ msg, date ("H: I: s"), 'process execution completed '); self: $ finished ++;} self: flush ($ msg, $ nomsg_interval ); self: $ running --; return;} else {goto label_wait; }}$ nomsg_in Terval = time (); self: flush ($ msg, $ nomsg_interval);} else {if ($ nomsg_interval! = Time () {foreach (self: $ childs as $ msg => $ t) {if (! Msg_queue_exists ($ msg) {goto label_child_exit;} echo "\ 33 [0; 0 H"; $ lines = intval ('tput Lines '); echo "\ 33 [K running duration:", self: run_time (), '', date (" Y-m-d H: I: s ", self :: $ start), '-', date ("Y-m-d H: I: s"), "\ 33 [$ lines; 0 H ";} usleep (100000);} goto label_wait;} static function running y ($ msg) {msg_send (self ::$ parent, 3, self ::$ msg. date ("H: I: s "). $ msg, false);} static function message ($ msg, $ code = 0) {switch ($ code) {case 0: echo "\ 33 [37m prompt: \ 33 [0 m", $ msg, "\ n"; break; case 1: echo "\ 33 [33m warning: \ 33 [0 m", $ msg, "\ n"; break; case 2: echo "\ 33 [31m error: \ 33 [0 m ", $ msg," \ n "; break ;}} static function confirm ($ msg =" OK to continue executing ") {echo $ msg, "(yes/no )?: "; # Return" yes \ n "= fgets (STDIN);} static function help ($ code = 0) {echo "\ n please use $ _ ENV [_] -- help to view help! \ N "; $ code & exit ($ code);} static function usage () {$ bat = _ CLASS __; echo" "," Usage: \ n ", "$ _ ENV [_] [options] [-f | -- file]
 
  
\ N "," Options: \ n ","-h | -- help: Display the help information \ n ","-v | -- version: view the program version \ n ", "\ n", "-m | -- max
  
   
Number of processes simultaneously executed. default value: ", self: $ max," \ n ","-l | -- log
   
    
Error log file. default value: ", self: $ logfile," \ n "," Information: \ n "," $ bat: run (fun [, arg]) to add task \ n "," fun is the name of the function to be executed; arg is the parameter passed to this function, which can save \ n "," \ n ", "The script calls $ bat: start () to start the process to execute the added task \ n", "in the sub-process, by calling $ bat: running y (msg) send the information to be displayed to the parent process \ n "," in the child process, an error occurs in program execution. to make the main process count as failed, exit (num) is required) non-zero return \ n "; exit;} static function version () {return" Version: 0.1 by huye \ n ";} static private function inc ($ file) {include $ File;} static private function end () {$ cols = intval ('tput cols'); $ lines = intval ('tput Lines'); if (self: $ total) {self: flush ("execution completed. ", 1); echo" \ 33 [$ lines; {$ cols} H \ 33 [1C \ n ";} if (is_file (self: $ logfile )) echo "\ 33 [K error:", self: $ logfile, "\ n"; echo "\ 33 [K running duration:", self :: run_time (), '', date (" Y-m-d H: I: s ", self: $ start ),'-', date ("Y-m-d H: I: s"), "\ n"; echo "\ 33 [K completed: completed task", self: $ finishe D, "count", self: $ failure? ", Failed". self: $ failure. ":" ", self: $ total? "(Total". self: $ total )":"",". \ N ";} static private function flush ($ msg, $ time) {$ cols = intval ('tput cols'); $ lines = intval ('tput Lines '); if ($ msg) {$ _ max = $ cols; foreach (explode ("\ n", $ msg) as $ msg) {if ($ cols <strlen ($ msg) {# ascii utf8 ascii utf8 ascii... $ tmp = preg_split ("#((?: [\ Xe0-\ xef] [\ x80-\ xbf] {2}) +) # ", $ msg, 0, PREG_SPLIT_DELIM_CAPTURE); for ($ I = 0, $ l = count ($ tmp); $ I <$ l;) {$ x = strlen ($ z = $ tmp [$ I]); if ($ _ max >$ x) {_ _ max-= $ x; if (++ $ I >=$ l) break; $ x = strlen ($ z = $ tmp [$ I])/3*2; if ($ _ max> $ x) {$ _ max-= $ x; $ I ++; continue;} elseif ($ _ max <$ x) {$ _ max = floor ($ _ max/2) * 3; $ msg = array_slice ($ tmp, $ I-1); $ msg [0] = ''; $ msg [1] = substr ($ z, $ _ max ); $ tmp [$ I] = substr ($ z, 0, $ _ max);} else {$ msg = array_slice ($ tmp, $ I + 1 );}} elseif ($ _ max <$ x) {$ msg = array_slice ($ tmp, $ I); $ msg [0] = substr ($ z, $ _ max ); $ tmp [$ I] = substr ($ z, 0, $ _ max);} else {$ msg = array_slice ($ tmp, $ I ); $ msg [0] = '';} if (++ $ I <$ l) {array_splice ($ tmp, $ I );} if (isset ($ msg [1]) {self: $ msgs [] = implode ("", $ tmp); $ msg [0] = "". $ msg [0]; $ I = 0; $ l = count ($ msg); $ tmp = $ msg; $ _ m Ax = $ cols;} elseif (isset ($ msg [0]) & strlen ($ msg [0]) {self :: $ msgs [] = implode ("", $ tmp); if ($ cols-15 <strlen ($ msg [0]) {foreach (str_split ($ msg [0], $ cols-15) as $ tmp) {$ tmp = "". $ tmp; if ($ cols = strlen ($ tmp) {self ::$ msgs [] = $ tmp;} else {$ tmp = array ($ tmp ); break ;}} else {$ tmp = array ("". $ msg [0]);} break;} else {break;} self: $ msgs [] = implode ("", $ tmp);} else {self :: $ msgs [] = $ Msg ;}} else {self: $ msgs [] = $ msg;} static $ last_time = 0; if ($ last_time = $ time) return true; $ last_time = $ time; # prevent screen flushing when remote ssh occurs echo "\ 33 [0; 0 H"; # echo "\ 33 [K program information:", self:: version (); echo "\ 33 [K running duration:", self: run_time (), '', date (" Y-m-d H: I: s ", self: $ start), '-', date (" Y-m-d H: I: s ")," \ n "; if ($ lines <5) {if ($ lines <3) return;} else {echo $ split = substr (self: $ split, 0, $ cols ),"\ N "; if ($ _ max = count (self: $ msgs) + 4)> $ lines) {array_splice (self: $ msgs, 0, $ _ max-$ lines);} elseif ($ lines >$ _ max) {$ split = str_repeat ("\ n \ 33 [K ", $ lines-$ _ max ). $ split;} echo "\ 33 [K", implode ("\ n \ 33 [K", self: $ msgs), "\ n", $ split, "\ n" ;}$ msg = "completed task ". self: $ finished. "; if (self: $ failure) $ msg. = ", failed ". self: $ failure. "; if (self: $ total) $ msg. = "(total ". self: $ total.") "; Echo str_repeat ('', $ cols-strlen (preg_replace ("# [\ xe0-\ xef] [\ x80-\ xbf] {2 }#", "**", $ msg), $ msg, "\ 33 [$ lines; 0 H";} static function run_time () {$ consume = time () -self: $ start; $ str = ""; if ($ consume >=86400) {$ str = floor ($ consume/86400 ). "Day"; $ consume = $ consume % 86400; $ zero = true;} if ($ consume >=3600) {$ str. = floor ($ consume/3600 ). "hour"; $ consume = $ consume % 3600; $ zero = True;} elseif ($ consume> 0 & isset ($ zero) {unset ($ zero); $ str. = "zero";} if ($ consume >=60) {$ str. = floor ($ consume/60 ). "points"; $ consume = $ consume % 60; $ zero = true;} elseif ($ consume> 0 & isset ($ zero) {unset ($ zero ); $ str. = "0";} if ($ consume> 0) {$ str. = $ consume. "Seconds";} elseif ($ str = "") {$ str = "0 seconds";} return $ str;} static function error ($ no, $ err, $ file, $ line) {if (error_reporting ()) {$ Log = $ no & 1032? & Apos; M & apos;: ($ no & 514? 'W': ($ no & 2048? 'M': 'e'); $ log = "[". date ("m-d H: I: s "). "] $ log $ line $ file $ err \ n"; file_put_contents (self ::$ logfile, $ log, FILE_APPEND) ;}} static function shutdown () {if ($ last = error_get_last () and 85 & $ last ['type']) {self: error ($ last ['type'], $ last ['message'], $ last ['file'], $ last ['line']); self ::$ get | self: end ();} if (self ::$ get) {msg_send (self ::$ parent, 4, getmypid (), false); # notifies the parent process to end self ::$ parent = self :: $ get; # it also prevents the failure of the previous row of notification ob_end_clean ();} msg_remove_queue (self ::$ parent);} static function exception ($ e) {self :: error ($ e-> getCode (), $ e-> getMessage (), $ e-> getFile (), $ e-> getLine ()); exit ($ e-> getCode () ;}} bat: main ();
   
  
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.