上一篇文章只是实现了其并发功能,前一个请求的处理不会阻碍下一个请求的处理,但是是每次请求的时候产生一个新的进程,也不是很好,并且并发的效果并不好,因为只有一个进程在工作。
这次的改进是,将生成多个工作进程,提高并发性能。
贴代码:
#!/usr/local/php5.3/bin/php <?php //多进程--预先生成固定进程的数量来处理请求。 error_reporting(0); set_time_limit(0); ob_implicit_flush(); date_default_timezone_set("Asia/Shanghai"); $debug = false; $user=''; $worker_processes=0; $listen_ip = "127.0.0.1"; $listen_port = 80; $vhosti = array(); //解析配置文件 function pare_conf_file(){ global $user,$worker_processes,$listen_ip,$listen_port,$vhost; $ini_array = parse_ini_file("./http.ini", true); $user=$ini_array['user']; $worker_processes=$ini_array['worker_processes']; $listen_ip = $ini_array['listen_ip']; $listen_port = $ini_array['listen_port']; $vhost = $ini_array['vhost']; } pare_conf_file(); //不存在的http方法响应 function response_method_404(){ $result = ""; $result .="HTTP/1.1 404\r\n"; $result .="Content-Length: 14\r\n"; $result .= "Content-Type: text/html\r\n"; $result .="\r\nserver is not \r\n"; return $result; } //不存在的文件响应 function response_file_404(){ $result = ""; $result .="HTTP/1.1 404\r\n"; $result .="Content-Length:0\r\n"; $result .= "Content-Type: text/html\r\n"; $result .="\r\n\r\n"; return $result; } //不支持文件的类型响应 function response_file_type_404(){ $result = ""; $result .="HTTP/1.1 404\r\n"; $result .="Content-Length:11\r\n"; $result .= "Content-Type: text/html\r\n"; $result .="\r\ntype is not\r\n"; return $result; } //图片类型响应 function response_file_img($fileurl){ $type = mime_content_type($fileurl); $body = file_get_contents($fileurl); $len = strlen($body); $result=""; $result .="HTTP/1.1 200\r\n"; $result .="Content-Length:$len\r\n"; $result .= "Content-Type: {$type}\r\n"; $result .="\r\n$body\r\n"; return $result; } //JS类型响应 function response_file_js($fileurl){ global $request; $body = file_get_contents($fileurl); $len = strlen($body); $date = date('D, d M Y G:i:s ').'GMT'; clearstatcache(); $last_modified = date('D, d M Y G:i:s ',filemtime($fileurl)).'GMT'; $result=""; $result .="HTTP/1.1 200\r\n"; $result .="Cache-Control: public\r\n"; $result .="Date:$date\r\n"; $result .="Last-Modified:$last_modified\r\n"; $result .="Expires:Fri, 24 Jan 2016 10:06:05 GMT\r\n"; $result .="Content-Length:$len\r\n"; $result .= "Content-Type: application/x-javascript\r\n"; $result .="\r\n$body\r\n"; return $result; } //HTML类型响应 function response_file_html($fileurl){ $body = file_get_contents($fileurl); $len = strlen($body); $result = ""; $result .="HTTP/1.1 200\r\n"; $result .="Content-Length:$len\r\n"; $result .= "Content-Type: text/html;charset=utf-8\r\n"; $result .="\r\n$body\r\n"; return $result; } //解析http请求 function pare_request($str){ clearstatcache(); global $web_root,$request; $arr = explode("\r\n",$str); foreach( $arr as $r){ $pos = stripos($r,":"); if ( $pos ){ $key = trim(substr($r,0,$pos)); $val = trim(substr($r,$pos+1)); $request[$key] = $val; } } writelog(var_export($request,true)); $line0 = explode(" ",$arr[0]); if ( $line0[0] == "GET" ){ $fileurl = $web_root.$line0[1]; if ( file_exists($fileurl) ){ $pathinfo = pathinfo($fileurl); if ( $pathinfo['extension'] == "js" ){ $result = response_file_js($fileurl); }else if ( $pathinfo['extension'] == "png" || $pathinfo['extension'] == "jpg" || $pathinfo['extension'] == "gif" ){ $result = response_file_img($fileurl); }else if ( $pathinfo['extension'] == "html" ){ $result = response_file_html($fileurl); }else{ $result = response_file_type_404(); } }else{ $result = response_file_404(); } }else{ $result = response_method_404(); } return $result; } //信号处理 function sig_handler($signo) { switch ($signo) { case SIGTERM:// 处理中断信号 echo "SIGTERM\r\n"; exit; break; case SIGHUP: // 处理重启信号 echo "SIGHUP\r\n"; exit; break; default: echo $signo."DEFAULT\r\n"; exit; // 处理所有其他信号 } } //安装信号处理器 function register_sig_handler(){ pcntl_signal(SIGTERM, "sig_handler"); pcntl_signal(SIGHUP, "sig_handler"); pcntl_signal(IGCHLD, "sig_handler" ); } //日志 function writelog($msg){ global $debug; if ( $debug ){ echo $msg; }else{ file_put_contents('./log.txt',$msg,FILE_APPEND | LOCK_EX); } } //切换用户 if ( $user ){ $user_info = posix_getpwnam($user); $uid = $user_info['uid']; }else{ $uid = posix_getuid(); } posix_setuid($uid); //调试模式判断 if ( !$debug ){ //产生子进程分支 $pid = pcntl_fork(); if ($pid == -1) { writelog("could not fork\r\n"); die("could not fork"); //pcntl_fork返回-1标明创建子进程失败 } else if ($pid) { exit(); //父进程中pcntl_fork返回创建的子进程进程号 } else { // 子进程pcntl_fork返回的时0 } // 从当前终端分离 if (posix_setsid() == -1) { writelog("could not detach form terminal \r\n"); die("could not detach from terminal"); } register_sig_handler(); } $address = '127.0.0.1'; $port = 1215; $web_root = "/home/xtgxiso/phpsource/socket"; $request = array(); $sock = false; //创建监听socket function listen_server_socket(){ global $sock,$address,$port; if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { writelog("socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"); exit; } socket_set_nonblock($sock); if (socket_bind($sock, $address, $port) === false) { writelog("socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"); exit; }else{ writelog('Socket ' . $address . ':' . $port . " has been opened\n"); } if (socket_listen($sock, 5) === false) { writelog("socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"); exit; }else{ writelog("Listening for new clients..\n"); } } listen_server_socket(); //创建工作进程 function start_work_process(){ global $sock,$client_id; $pid = pcntl_fork(); if ( $pid == 0 ){ do{ if ( ($msgsock = socket_accept($sock)) === false ) { writelog("socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"); usleep(5000); continue; } else { $client_id += 1; writelog(date('Y-m-d G:i:s')."--Client #" .$client_id .": Connect\n"); } socket_close($sock); $cur_buf = ''; do { if (false === ($buf = socket_read($msgsock, 2048))) { writelog("socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"); break; } writelog("read start:\r\n"); writelog($buf); writelog("read end:\r\n\r\n"); $talkback = pare_request($buf); writelog("\r\nwrite start:\r\n"); socket_write($msgsock, $talkback, strlen($talkback)); //writelog($talkback); writelog("write end:\r\n\r\n\r\n"); break; } while (true); socket_close($msgsock); }while(true); }else if ( $pid > 0 ){ socket_close($sock); } } //创建工作进程并处理信号 $client_id = 0; for( $i = 1; $i <= $worker_processes;$i++){ start_work_process(); } while(1){ sleep(1); } writelog("socket_close \r\n"); socket_close($sock);
这样就可以提前生成比如:10个进程。一下子能力提高了10倍 。这个程序并没有将工作进程中的每个请求创建新的进程来处理(性能不太好),要是能够用线程来解决就好了。
The point of the bill is so that by 2020
christina aguilera weight loss Top 7 Formulas for Writing Articles That Get Read
negative aspects at dress for youths
miranda lambert weight lossAdvice on What to Wear at a 70s Party
miranda lambert weight lossAdvice on What to Wear at a 70s Party