<?php
   $key = ftok(__FILE__, 's');
   // 同时最多只能有一个进程进入临界区
   $sem_id = sem_get($key, 1);
   echo "This is a room,can only stay one people!\n\r";
   // 派生子进程
   $pid = pcntl_fork();
   if ($pid == -1) {
      exit('fork failed!');
   } else if ($pid > 0) {
      $name = 'parent';
   } else {
      $name = 'child';
   }
   echo "{$name} want to enter the room \n";
   sem_acquire($sem_id);
   // 原子操作开始
   echo "{$name} in the room , other people can't enter!\n";
   sleep(3);
   echo "{$name} leave the room\n";
   // 原子操作结束
   sem_release($sem_id);
   if ($pid > 0) {
      pcntl_waitpid($pid, $status);
      sem_remove($sem_id);//移除信号量
   }
?>PHP进程间通信System V信号量
发布时间:January 9, 2014 // 分类:PHP // No Comments
PHP进程间通信System V共享内存
发布时间:January 9, 2014 // 分类:PHP // No Comments
Yum安装的PHP需安装扩展包php-process:
<?php 
   $shm_key = intval(bin2hex('node'), '16');               
   $memsize = 120;
   $shm_h = shm_attach($shm_key, $memsize, 0644);
   $var_key = intval(bin2hex('key'), '16'); 
   $var_value = 'hello';
   shm_put_var($shm_h, $var_key, $var_value);
   echo shm_get_var($shm_h, $var_key);
   shm_remove_var($shm_h, $var_key);
   shm_detach($shm_h);
?>PHP进程间通信System V消息队列
发布时间:January 9, 2014 // 分类:PHP // No Comments
多进程:
<?php
   //生成key
   $message_queue_key = ftok(__FILE__, 'a');
   //根据生成的key新建队列,也可自定,如123456
   $message_queue = msg_get_queue($message_queue_key, 0666);
   $pids = array();
   for ($i = 0; $i < 5; $i++) {
      //创建子进程
      $pids[$i] = pcntl_fork();
      if ($pids[$i]) {
         echo "No.$i child process was created, the pid is $pids[$i]\r\n";
         pcntl_wait($status);//非阻塞的线程等待,防止僵尸进程的出现
      } elseif ($pids[$i] == 0) {
         $pid = posix_getpid();
         echo "process.$pid is writing now\r\n";
         //写队列
         msg_send($message_queue, 1, "this is process.$pid's data\r\n");
         posix_kill($pid, SIGTERM);
      }
   }
   do {
      //读队列
      msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
      echo $message;
      //获取队列内消息数
      $a = msg_stat_queue($message_queue);
      if($a['msg_qnum'] == 0){
         break;
      }
   } while(true)
?>父子进程:
<?php
   $message_queue_key = ftok(__FILE__, 'a');
   $message_queue = msg_get_queue($message_queue_key, 0666);
   $pid = pcntl_fork();
   if ($pid==-1) {
      die("cannot fork");
   } else if ($pid) { //父进程
      pcntl_wait($status);
      msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT);
      echo $message;
   } else {
      $pid = posix_getpid(); //子进程
      msg_send($message_queue, 1, "this is process.$pid's data\r\n");
   }
?>PHP异步并发执行multi cURL详解
发布时间:January 4, 2014 // 分类:PHP // No Comments
官方提供的例子,一次执行多个连接,然后阻塞所有链接完成取内容,整个过程是阻塞的。
<?php
// 创建单个cURL资源
$ch1 = curl_init();
$ch2 = curl_init();
// 设置URL和相应的选项
curl_setopt($ch1, CURLOPT_URL, "https://www.haiyun.me/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch2, CURLOPT_URL, "https://www.haiyun.me/");
curl_setopt($ch2, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 增加单个句柄到批处理
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
$active = null;
// 执行批处理句柄,循环任务直到全部执行,不等待返回结果
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
//循环判断任务是否执行完成
while ($active && $mrc == CURLM_OK) {
    //阻塞等待cURL批处理中的活动连接,失败时返回-1,不等于-1代表还有活动连接
    if (curl_multi_select($mh) != -1) {
        //有活动连接时继续执行批处理句柄
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}
//获取单个URL返回的内容
var_dump(curl_multi_getcontent($ch1));
// 关闭全部句柄
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
?>非阻塞实现http://code.google.com/p/rolling-curl/,不过在循环时是根据curl_multi_exec返回的运行状态判断的,大量链接时经常没完成就跳出,修改了下根据循环的队列是否完成来判断。
<?php
   $isruning = 1;
   do {
      //执行句柄内所有连接,包括后来新加入的连接
      do {
         $execrun = curl_multi_exec($master, $running);
      } while ($execrun == CURLM_CALL_MULTI_PERFORM);
      //while (($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM) ;
      //if ($execrun != CURLM_OK)
      //break;
      //有连接返回立即处理,并加入新的连接
      while ($done = curl_multi_info_read($master)) {
         //获取返回的信息
         $info = curl_getinfo($done['handle']);
         $output = curl_multi_getcontent($done['handle']);
         //发送返回信息到回调函数
         $callback = $this->callback;
         if (is_callable($callback)) {
            //获取返回信息的句柄
            $key = (string) $done['handle'];
            //根据请求映射是哪个请求返回的信息
            $request = $this->requests[$this->requestMap[$key]];
            unset($this->requestMap[$key]);
            call_user_func($callback, $output, $info, $request);
         }
         //判断队列内的连接是否用完
         if ($i < sizeof($this->requests) && isset($this->requests[$i]) && $i < count($this->requests)) {
            $ch = curl_init();
            $options = $this->get_options($this->requests[$i]);
            curl_setopt_array($ch, $options);
            //增加新的连接
            curl_multi_add_handle($master, $ch);
            //添加到request Maps,用于返回信息时根据handle找到相应连接
            $key = (string) $ch;
            $this->requestMap[$key] = $i;
            $i++;
         } 
         else {
            //循环结束
            $isruning = 0;
         }
         //删除完成的句柄
         curl_multi_remove_handle($master, $done['handle']);
      }
      // Block for data in / output; error handling is done by curl_multi_exec
      if ($running)
      curl_multi_select($master, $this->timeout);
   } while ($isruning);
?>PHP函数pfsockopen建立Keep-Alive连接
发布时间:January 1, 2014 // 分类:PHP // No Comments
使用Keep-Alive可减少建立TCP连接的开销,pfsockopen在脚本执行期间可重用socket实现Keep-Alive。
<?php
   function httpget($host)   
   {   
      $conn = pfsockopen($host,80,$errno, $errstr, 30);   
      if (!$conn)    
      {   
         echo "$errstr ($errno)<br />\n";   
         return;   
      }   
      $header = "HEAD / HTTP/1.1\r\n";   
      $header.= "Host: {$host}\r\n";   
      $header.= "Connection: Keep-Alive\r\n\r\n";    
      fwrite($conn,$header);   
      /*
      while (!feof($conn)) {   
         $resp .= fgets($conn);   
      }
      */
      //fclose($conn); //关闭连接后再连接keepalive失效
      return $resp;   
   }   
   $host = 'www.haiyun.me';   
   $count = 2;   
   for ($i = 0; $i < $count; $i++) {   
      echo httpget($host);
      sleep(10);
   }   
?>Tcpdump分析,1-3行第一次建立TCP连接,第8行建立第二次连接跳过TCP三次握手。
20:27:17.016435 IP 1.2.3.4.49022 > 162.211.225.71.80: Flags [S], seq 2231661196, win 5840, options [mss 1400,sackOK,TS val 9961058 ecr 0,nop,wscale 6], length 0
20:27:17.016531 IP 162.211.225.71.80 > 1.2.3.4.49022: Flags [S.], seq 2734092091, ack 2231661197, win 14480, options [mss 1460,sackOK,TS val 1880475065 ecr 9961058,nop,wscale 7], length 0
20:27:17.342653 IP 1.2.3.4.49022 > 162.211.225.71.80: Flags [.], ack 1, win 92, options [nop,nop,TS val 9961139 ecr 1880475065], length 0
20:27:17.345695 IP 1.2.3.4.49022 > 162.211.225.71.80: Flags [P.], seq 1:65, ack 1, win 92, options [nop,nop,TS val 9961139 ecr 1880475065], length 64
20:27:17.345716 IP 162.211.225.71.80 > 1.2.3.4.49022: Flags [.], ack 65, win 114, options [nop,nop,TS val 1880475394 ecr 9961139], length 0
20:27:17.876911 IP 162.211.225.71.80 > 1.2.3.4.49022: Flags [P.], seq 1:427, ack 65, win 114, options [nop,nop,TS val 1880475925 ecr 9961139], length 426
20:27:18.202503 IP 1.2.3.4.49022 > 162.211.225.71.80: Flags [.], ack 427, win 108, options [nop,nop,TS val 9961355 ecr 1880475925], length 0
20:27:27.346477 IP 1.2.3.4.49022 > 162.211.225.71.80: Flags [P.], seq 65:129, ack 427, win 108, options [nop,nop,TS val 9963640 ecr 1880475925], length 64
20:27:27.346508 IP 162.211.225.71.80 > 1.2.3.4.49022: Flags [.], ack 129, win 114, options [nop,nop,TS val 1880485395 ecr 9963640], length 0
20:27:27.838571 IP 162.211.225.71.80 > 1.2.3.4.49022: Flags [P.], seq 427:853, ack 129, win 114, options [nop,nop,TS val 1880485887 ecr 9963640], length 426
20:27:28.165367 IP 1.2.3.4.49022 > 162.211.225.71.80: Flags [.], ack 853, win 125, options [nop,nop,TS val 9963845 ecr 1880485887], length 0
20:27:37.346030 IP 1.2.3.4.49022 > 162.211.225.71.80: Flags [R.], seq 129, ack 853, win 125, options [nop,nop,TS val 9966140 ecr 1880485887], length 0分类
- Apache (13)
- Nginx (45)
- PHP (86)
- IIS (8)
- Mail (17)
- DNS (16)
- Cacti (14)
- Squid (5)
- Nagios (4)
- Puppet (7)
- CentOS (13)
- Iptables (23)
- RADIUS (3)
- OpenWrt (41)
- DD-WRT (1)
- VMware (9)
- 网站程序 (2)
- 备份存储 (11)
- 常用软件 (20)
- 日记分析 (10)
- Linux基础 (18)
- 欧诺代理 (0)
- Linux服务 (18)
- 系统监控 (4)
- 流量监控 (7)
- 虚拟化 (28)
- 伪静态 (2)
- LVM (3)
- Shell (18)
- 高可用 (2)
- 数据库 (16)
- FreeBSD (3)
- 网络安全 (25)
- Windows (35)
- 网络工具 (22)
- 控制面板 (3)
- 系统调优 (10)
- Cisco (3)
- VPN (6)
- ROS (20)
- Vim (14)
- KMS (4)
- PXE (2)
- Mac (1)
- Git (1)
- PE (1)
- LNS (2)
- Xshell (7)
- Firefox (13)
- Cygwin (4)
- OpenSSL (9)
- Sandboxie (3)
- StrokesPlus (1)
- AutoHotKey (4)
- Total Commander (3)
- WordPress (3)
- iMacros (6)
- Typecho (2)
- Ollydbg (1)
- Photoshop (1)
- 正则 (3)
- Debian (3)
- Python (8)
- NoSQL (6)
- 消息队列 (4)
- JS (7)
- Tmux (3)
- GO (7)
- HHVM (2)
- 算法 (1)
- Docker (2)
- PT (15)
- N1 (16)
- K2P (6)
- LUKS (4)
最新文章
- sandboxie plus运行firefox 140播放视频全屏不能覆盖任务栏
- TEWA-1100G光猫使用
- 烽火光猫HG5382A3使用
- 记联通更换移动XG-040G-MD光猫
- smokeping slave同步错误illegal attempt to update using time解决
- 使用valgrind定位解决smartdns内存泄露
- 此内容被密码保护
- debian12下initramfs-tools配置ip子网掩码255.255.255.255/32失败解决
- iPhone查看屏幕供应商
- 光猫拨号ImmortalWrt/OpenWRT路由获取ipv6遇到的问题