1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?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:
1 2 3 4 5 6 7 8 9 10 11 | <?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
多进程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?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) ?> |
父子进程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?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
官方提供的例子,一次执行多个连接,然后阻塞所有链接完成取内容,整个过程是阻塞的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <?php // 创建单个cURL资源 $ch1 = curl_init(); $ch2 = curl_init(); // 设置URL和相应的选项 curl_setopt( $ch1 , CURLOPT_HEADER, 0); curl_setopt( $ch1 , CURLOPT_RETURNTRANSFER, 1); 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返回的运行状态判断的,大量链接时经常没完成就跳出,修改了下根据循环的队列是否完成来判断。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <?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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?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三次握手。
1 2 3 4 5 6 7 8 9 10 11 12 | 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)
最新文章
- 记联通更换移动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遇到的问题
- php-fpm错误error_log日志配置
- debian-12/bookworm安装mariadb10.3和mysql5.6
- smokeping主从配置及遇到的问题
最近回复
- opnfense: 谢谢博主!!!解决问题了!!!我之前一直以为内置的odhcp6就是唯一管理ipv6的方式
- liyk: 这个方法获取的IPv6大概20分钟之后就会失效,默认路由先消失,然后Global IPV6再消失
- 海运: 不好意思,没有。
- zongboa: 您好,請問一下有immortalwrt設定guest Wi-Fi的GUI教學嗎?感謝您。
- 海运: 恩山有很多。
- swsend: 大佬可以分享一下固件吗,谢谢。
- Jimmy: 方法一 nghtp3步骤需要改成如下才能编译成功: git clone https://git...
- 海运: 地址格式和udpxy一样,udpxy和msd_lite能用这个就能用。
- 1: 怎么用 编译后的程序在家里路由器内任意一台设备上运行就可以吗?比如笔记本电脑 m参数是笔记本的...
- 孤狼: ups_status_set: seems that UPS [BK650M2-CH] is ...