海运的博客

PHP多进程同时写文件

发布时间:December 1, 2013 // 分类:PHP // No Comments

使用系统提供的flock函数:

<?php
   function ffwrite($filename,$content) {
      $file = fopen("$filename","a");
      while(1) {
         if (flock($file,LOCK_EX))
         {
            fwrite($file,$content);
            flock($file,LOCK_UN);
            fclose($file);
            break;
            } else {
            usleep(1000);
         }
      }
   }
?>

或根据创建文件判断其它进程是否在写操作,性能略差,测试1000次20进程写操作慢3%。

<?php
 function _fwrite($filename, $content) {
     $filename_lock = $filename . '.lock';
     while(1)
     {
         if(file_exists($filename_lock))
            {
             usleep(1000);
             } else {
             touch($filename_lock); 
             $f = fopen($filename, 'a');
             fwrite($f, "$content");
             fclose($f);
             unlink($filename_lock);
             break;
             }       
         }
     if(file_exists($filename_lock))
        {
         unlink($filename_lock);
         }
     }
 ?>

PHP读取大文件指定行

发布时间:December 1, 2013 // 分类:PHP // No Comments

<?php
 function getFileLines($filename, $startLine = 1, $endLine = 50, $method = 'rb'){
     $content = array();
    
     if (version_compare(PHP_VERSION, '5.1.0', '>=')){ // 5.1版本之上使用Splfileobject
         $count = $endLine - $startLine;
         $fp = new SplFileObject($filename, $method);
         $fp -> seek($startLine - 1); // 转到$startLine行,seek方法从0开始计数
         for ($i = 0; $i <= $count; ++$i){
             $content[] = trim(($fp -> current()), "\n"); //current()方法取当前行清除换行保存到数组
             $fp -> next(); //循环下一行
             }
         }else{ // PHP<5.1
         $fp = fopen($filename, $method);
         if (!$fp)
             return 'error:can not read file';
         for ($i = 1; $i < $startLine; ++$i){ //定位到$startLine行
             fgets($fp);
            }
        
        for ($i; $i <= $endLine; ++$i){
             $content[] = fgets($fp); //从$startLine行开始循环读取到$endLine行
            }
        fclose($fp);
        }
    return array_filter($content); //返回array_filter(flase,null,0)过滤后的数组
    }
?>

示例:

<?php
$filename = 'file.txt';
$start = 1;
$end = 10;
$count = $end - $start;
while (true){
     $data = getFileLines($filename, $start, $end);
     // var_dump($data);
    $rev = ver($data);
     if($data[9] == ''){
         die("End");
         sleep(10);
        }
    $start = $start + 10;
    $end = $end + 10;
    }
?>

PHP计算脚本执行时间

发布时间:December 1, 2013 // 分类:PHP // No Comments

<?php
   $start = microtime ( true ); 
   sleep(2);
   $end = microtime ( true ); 
   echo "脚本执行时间".($end - $start)."\n";  
?>

PHP多进程

发布时间:November 26, 2013 // 分类:PHP // No Comments

<?php
function convert($size)
{
  $unit=array('b','kb','mb','gb','tb','pb');
  return @round($size/pow(1024,($i=floor(log($size,1024)))),2).$unit[$i];
}
$childs = array();

for($i = 0; $i < 10; $i++) {
  $pid = pcntl_fork();
  if($pid == -1)
    die('Could not fork');

  if ($pid) { //主进程执行
    echo "parent \n";
    $childs[] = $pid;
  } else { //子进程执行
    for($i =1;$i<10;$i++)
    {
      $pid = posix_getpid();
      echo '当前进程'.$pid.PHP_EOL;
      echo '当前循环'.$i.PHP_EOL;
      echo '占用内存'.convert(memory_get_usage()) . PHP_EOL;
      sleep(1);
    }
    exit();
  }
}

while(count($childs) > 0) {
  foreach($childs as $key => $pid) {
    $res = pcntl_waitpid($pid, $status, WNOHANG);

    if($res == -1 || $res > 0)
      unset($childs[$key]);
  }
  sleep(1);
}

或:

<?php
   function convert($size)
   {
      $unit=array('b','kb','mb','gb','tb','pb');
      return @round($size/pow(1024,($i=floor(log($size,1024)))),2).$unit[$i];
   }
   //最大的子进程数量
   $maxChildPro = 8;
   //当前的子进程数量
   $curChildPro = 0;

   //当子进程退出时,会触发该函数
   function sig_handler($sig)
   {
      global $curChildPro;
      switch($sig)
      { 
         case SIGCHLD:  
         //当前进程数减一,同时控制段会启动一新进程
         $curChildPro--;
         break;
      }
   }

   //配合pcntl_signal使用,简单的说,是为了让系统产生时间云,让信号捕捉函数能够捕捉到信号量
   declare(ticks=1);

   //注册子进程退出时调用的函数。SIGCHLD:在一个进程终止或者停止时,将SIGCHLD信号发送给其父进程。
   pcntl_signal(SIGCHLD, "sig_handler");
   //整个任务控制
   for ($i = 1; $i <= 5; $i++) 
   //while(true)
   {
      $curChildPro++;
      $pid = pcntl_fork();
      if ($pid)    //父进程运行代码
      {
         if ($curChildPro >= $maxChildPro)
         {
            pcntl_wait($status);
         } 
      }
      else        //子进程运行代码
      {
         //子进程多次循环使用再退出
         for($i =1;$i<10;$i++)
         {
            echo '当前进程'.$curChildPro.PHP_EOL;
            echo '当前循环'.$i.PHP_EOL;
            echo '占用内存'.convert(memory_get_usage()) . PHP_EOL;
            sleep(1);
         }
         exit; 
      }
   }

   //主进程等待所有子进程完成后再退出
   while ($curChildPro)
   {
      pcntl_wait($status);
      //各信号控制冲突,造成负数循环
      //$curChildPro--;
   }

PHP调用淘宝API获取用户IP信息

发布时间:November 4, 2013 // 分类:PHP // No Comments

<?php
header('Content-Type:text/html;charset=utf-8');
$ip = $_SERVER["REMOTE_ADDR"];
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "http://ip.taobao.com/service/getIpInfo.php?ip=$ip");
curl_setopt($ch, CURLOPT_REFERER, "http://www.test.com");
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11");
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,3);
curl_setopt($ch,CURLOPT_TIMEOUT,3);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$ipinfo=json_decode(curl_exec($ch),1);
echo $ipinfo[data][region].$ipinfo[data][city].$ipinfo[data][isp];
?>
分类
最新文章
最近回复
  • spartan2: https://dashboard.hcaptcha.com/welcome_accessib...
  • 海运: 应该能,在购买页面先手工跳过cf机器验证,后续一定时间内不更换ip应该不会再次验证。
  • spartan: 大佬斯巴达开启了CF的机器识别验证,请问插件能自动跳过吗? 另外这个脚本有没有简单使用说明,新...
  • vincent: 膜拜大佬
  • 海运: proxy-header或proxy_protocol
  • liangjw: 如果是 内部调用 或者 中间存在 代理 而上一个代理又在内网 ,那怎么处理来自代理私有IP?
  • chainofhonor: 感谢,用dnsmasq设置自动判断BIOS和UEFI成功了
  • 海运: 不好意思,这个是很多年前的,现在也许已经不适用,我现在也不用多线了。
  • CQ: -m state --state NEW 替换成-m conntrack --ctstate NEW
  • CQ: 你好,我入站已经成功分流,但是不知道出站怎么设置,PREROUTING替换成POSTROUTI...