mac下VirtualBox共享centos7文件解决方式

远程虚拟机以前请确认你是否?
1.设置共享目录
2.已下载扩展包
3.设置扩展包到对象虚拟机

#挂载需要的服务
yum -y install gcc++ gcc make kernel kernel-devel kernel-headers bzip2

#设置内核
ln -s /usr/src/kernels/3.10.0-327.28.2.el7.x86_64 /usr/src/linux

#挂载光驱

#创建光驱目录
mkdir /mnt/cdrom
#挂在光驱
mount /dev/cdrom /mnt/cdrom
#卸载光驱
umount /dev/cdrom /mnt/cdrom

#进入目录
cd /mnt/cdrom

#执行安装
./VBoxLinuxAdditions.run

#重起
shutdown -r now

#查看是否有vbox
ps -ef | grep -i vbox

#创建目录
mkdir /mnt/code

#挂载共享
mount -t vboxsf code /mnt/code

#重起
shutdown -r now

注意重起后会失效,需要在ssh脚本中进行设置

解决virtualbox最小化安装centos7后不能上网

#文件
vi /etc/sysconfig/network-scripts/ifcfg-enp0s3

#将
ONBOOT=no
#改为
ONBOOT=yes

#保存后重启网卡:

systemctl restart network.service

此时就可以上网了。

因为是最小化安装,此时ifconfig命令不能用,可用

#查看分配网卡情况命令
ip addr

#安装net-tools工具
yum -y install net-tools

#然后就可以正常的使用ifconfig

#如果有必要请
yum -y update

git小型团队,协作使用约定

#git分支约定

master = 正式版本
develop = 开发版本

#git定型版本tag

当每个develop版本合并至master分支以后,打git tag 1.1.2版本标签,便于版本细节变化操作的跟踪.

#bug相关

当正式版本产生bug的时候,可能需要修改代码,为了后期便于维护,请根据以下约定进行操作.

#本地场景操作->确认至本地master版本

git checkout master

#更新本地分支

git pull origin master

#创建本地bug分支版本

git branch bug#1.1.2

#修复以后的操作

git checkout master
``

#合并分支

git merge bug#1.1.2


#写入日记

git commit -m “日记,写入本地合并的操作相关信息”


#打标签

git tag -a 1.1.2 -m “Release version 1.1.2”


#详解 git tag命令

-a 1.1.2 是增加名为1.1.2的标签
-m 后面跟着的是标签的注释


#提交标签到远程服务器上

git push origin master
git push origin –tags
–tags参数表示提交所有tag至服务器端,普通的git push origin master操作不会推送标签到服务器端。


#删除标签的命令

git tag -d  1.1.2


#删除远端服务器的标签

git push origin :refs/tags/1.1.2
“`

php geohash附近算法和使用类

原理google

 

实现类

<?php

class Geohash {

    private $bitss = array(16, 8, 4, 2, 1);
    private $neighbors = array();
    private $borders = array();

    private $coding = "0123456789bcdefghjkmnpqrstuvwxyz";
    private $codingMap = array();

    /**
     * 实例化数据
     * Geohash constructor.
     */
    public function __construct()
    {
        $this->neighbors['right']['even'] = 'bc01fg45238967deuvhjyznpkmstqrwx';
        $this->neighbors['left']['even'] = '238967debc01fg45kmstqrwxuvhjyznp';
        $this->neighbors['top']['even'] = 'p0r21436x8zb9dcf5h7kjnmqesgutwvy';
        $this->neighbors['bottom']['even'] = '14365h7k9dcfesgujnmqp0r2twvyx8zb';

        $this->borders['right']['even'] = 'bcfguvyz';
        $this->borders['left']['even'] = '0145hjnp';
        $this->borders['top']['even'] = 'prxz';
        $this->borders['bottom']['even'] = '028b';

        $this->neighbors['bottom']['odd'] = $this->neighbors['left']['even'];
        $this->neighbors['top']['odd'] = $this->neighbors['right']['even'];
        $this->neighbors['left']['odd'] = $this->neighbors['bottom']['even'];
        $this->neighbors['right']['odd'] = $this->neighbors['top']['even'];

        $this->borders['bottom']['odd'] = $this->borders['left']['even'];
        $this->borders['top']['odd'] = $this->borders['right']['even'];
        $this->borders['left']['odd'] = $this->borders['bottom']['even'];
        $this->borders['right']['odd'] = $this->borders['top']['even'];

        //build map from encoding char to 0 padded bitfield
        for($i=0; $i<32; $i++)
        {
            $this->codingMap[substr($this->coding, $i, 1)] = str_pad(decbin($i), 5, "0", STR_PAD_LEFT);
        }

    }

    /**
     * 解密
     * @param 纬度,经度 lat,long in it
     */
    public function decode($hash)
    {

        //decode hash into binary string
        $binary = "";
        $hl = strlen($hash);
        for ($i=0; $i<$hl; $i++) {

            $binary .= $this->codingMap[substr($hash, $i, 1)];
        }

        //split the binary into lat and log binary strings
        $bl = strlen($binary);
        $blat = "";
        $blong = "";
        for ($i=0; $i<$bl; $i++) {

            if ($i%2)
                $blat=$blat.substr($binary, $i, 1);
            else
                $blong=$blong.substr($binary, $i, 1);

        }

        //now concert to decimal
        $lat = $this->binDecode($blat, -90, 90);
        $long = $this->binDecode($blong, -180, 180);

        //figure out how precise the bit count makes this calculation
        $latErr = $this->calcError(strlen($blat), -90, 90);
        $longErr = $this->calcError(strlen($blong), -180, 180);

        //how many decimal places should we use? There's a little art to
        //this to ensure I get the same roundings as geohash.org
        $latPlaces = max(1, -round(log10($latErr))) - 1;
        $longPlaces = max(1, -round(log10($longErr))) - 1;

        //round it
        $lat = round($lat, $latPlaces);
        $long = round($long, $longPlaces);

        return array($lat, $long);
    }


    private function calculateAdjacent($srcHash, $dir) {

        $srcHash = strtolower($srcHash);
        $lastChr = $srcHash[strlen($srcHash) - 1];
        $type = (strlen($srcHash) % 2) ? 'odd' : 'even';
        $base = substr($srcHash, 0, strlen($srcHash) - 1);

        if (strpos($this->borders[$dir][$type], $lastChr) !== false) {

            $base = $this->calculateAdjacent($base, $dir);
        }

        return $base . $this->coding[strpos($this->neighbors[$dir][$type], $lastChr)];
    }


    /**
     * 获取相对区域的8个位置
     * @param $srcHash
     * @return mixed
     */
    public function neighbors($srcHash)
    {

        $geohashPrefix = substr($srcHash, 0, strlen($srcHash) - 1);

        $neighbors['top'] = $this->calculateAdjacent($srcHash, 'top');
        $neighbors['bottom'] = $this->calculateAdjacent($srcHash, 'bottom');
        $neighbors['right'] = $this->calculateAdjacent($srcHash, 'right');
        $neighbors['left'] = $this->calculateAdjacent($srcHash, 'left');

        $neighbors['topleft'] = $this->calculateAdjacent($neighbors['left'], 'top');
        $neighbors['topright'] = $this->calculateAdjacent($neighbors['right'], 'top');
        $neighbors['bottomright'] = $this->calculateAdjacent($neighbors['right'], 'bottom');
        $neighbors['bottomleft'] = $this->calculateAdjacent($neighbors['left'], 'bottom');

        return $neighbors;
    }

    /**
     * 经纬度加密
     * @param $lat 纬度
     * @param $long 经度
     * @return string
     */
    public function encode($lat, $long)
    {

        //how many bits does latitude need?
        $plat = $this->precision($lat);
        $latbits = 1;
        $err = 45;
        while($err > $plat) {

            $latbits++;
            $err /= 2;
        }

        //how many bits does longitude need?
        $plong = $this->precision($long);
        $longbits = 1;
        $err = 90;
        while($err > $plong) {

            $longbits++;
            $err /= 2;
        }

        //bit counts need to be equal
        $bits = max($latbits, $longbits);

        //as the hash create bits in groups of 5, lets not
        //waste any bits - lets bulk it up to a multiple of 5
        //and favour the longitude for any odd bits
        $longbits = $bits;
        $latbits = $bits;
        $addlong = 1;
        while (($longbits + $latbits) % 5 != 0) {

            $longbits += $addlong;
            $latbits += !$addlong;
            $addlong = !$addlong;
        }


        //encode each as binary string
        $blat = $this->binEncode($lat, -90, 90, $latbits);
        $blong = $this->binEncode($long, -180, 180, $longbits);

        //merge lat and long together
        $binary = "";
        $uselong = 1;
        while (strlen($blat) + strlen($blong)) {

            if ($uselong) {

                $binary = $binary.substr($blong, 0, 1);
                $blong = substr($blong, 1);

            } else {

                $binary = $binary.substr($blat, 0, 1);
                $blat = substr($blat, 1);
            }

            $uselong = !$uselong;
        }

        //convert binary string to hash
        $hash = "";
        for ($i=0; $i<strlen($binary); $i+=5) {

            $n = bindec(substr($binary, $i, 5));
            $hash = $hash.$this->coding[$n];
        }

        return $hash;
    }

    /**
     * What's the maximum error for $bits bits covering a range $min to $max
     */
    private function calcError($bits, $min, $max)
    {

        $err = ($max - $min) / 2;
        while ($bits--)
            $err /= 2;
        return $err;
    }

    /*
    * returns precision of number
    * precision of 42 is 0.5
    * precision of 42.4 is 0.05
    * precision of 42.41 is 0.005 etc
    *
    * Author: Bruce Chen (weibo: @一个开发者)
    */
    private function precision($number)
    {

        $precision = 0;
        $pt = strpos($number,'.');
        if ($pt !== false) {

            $precision = -(strlen($number) - $pt - 1);
        }

        return pow(10, $precision) / 2;
    }


    /**
     * create binary encoding of number as detailed in http://en.wikipedia.org/wiki/Geohash#Example
     * removing the tail recursion is left an exercise for the reader
     *
     * Author: Bruce Chen (weibo: @一个开发者)
     */
    private function binEncode($number, $min, $max, $bitcount)
    {

        if ($bitcount == 0)
        {
            return '';
        }

        #echo "$bitcount: $min $max<br>";

        //this is our mid point - we will produce a bit to say
        //whether $number is above or below this mid point
        $mid = ($min + $max) / 2;
        if ($number > $mid)
            return "1" . $this->binEncode($number, $mid, $max, $bitcount - 1);
        else
            return "0" . $this->binEncode($number, $min, $mid, $bitcount - 1);
    }


    /**
     * decodes binary encoding of number as detailed in http://en.wikipedia.org/wiki/Geohash#Example
     * removing the tail recursion is left an exercise for the reader
     * Author: Bruce Chen (weibo: @一个开发者)
     */
    private function binDecode($binary, $min, $max)
    {

        $mid = ($min + $max) / 2;

        if (strlen($binary) == 0)
        {
            return $mid;
        }

        $bit = substr($binary, 0, 1);
        $binary = substr($binary, 1);

        if ($bit == 1)
        {
            return $this->binDecode($binary, $mid, $max);
        }
        else
        {
            return $this->binDecode($binary, $min, $mid);
        }
    }

}

使用方式

$geo = new Geohash();
$latitude = '120.33.22.3';
$longitude = '310.23.132';
//获取gao算法加密字符串
$geohashVal = $geo->encode($latitude,$longitude);

//把$geohashVal插入数据表即可

 #查询附近的人
 $geo = new Geohash();
 $geohash = $geo->encode($latitude,$longitude);
 //切割长度是位置的距离线 
 $prefix = substr($geohash, 0, 6);
 $so = array_values($geo->neighbors($prefix));
 
 //$so是一个索引二维数组,相对8个位置角度,具体可打印测试

非常角度的方式使用咯

 

 

开源中国的GIT webhook钩子的php版本

php代码

<?php
/**
 * 写日记
 * @param str $msg
 */
function writeLog($msg,$file='')
{
    date_default_timezone_set("Asia/Shanghai");
    $dir = __DIR__.'/log/';
    if(!empty($file))
    {
        $file = $dir.$file;
    }else{
    	$file = $dir.'hook.log';
    }

    if (!file_exists ( $file ))
    {
    	 touch ( $file );
    }
    $info = "\r\n".date('Y-m-d H/i/s').': '.$msg;
    $fh = fopen ( $file, 'a+' );
    fwrite ( $fh, $info);
    fclose ( $fh );
}

if(isset($_POST['hook']))
{
    
	$passwd = '';//这里是您的KEY
	$hookJson = $_POST['hook'];
	writeLog($hookJson,'hook_json.log');
	if($json = json_decode($hookJson))
	{
		if($json->password === $passwd)
		{
			echo exec('/root/toinwork.sh');
			writeLog('toinwork执行成功','success.log');
		}	
	}else{
		writeLog('toinwork,hook密码不正确..执行失败','failure.log');
	}
}

shell执行脚本

#!/bin/bash
WEB_PATH='you is path'
WEB_USER='nginx'
WEB_USERGROUP='nginx'

echo "Start deployment"
cd $WEB_PATH
echo "pulling source code..."
git reset --hard origin/develop
git clean -f
git pull
git checkout develop
echo "changing permissions..."
chown -R $WEB_USER:$WEB_USERGROUP $WEB_PATH
echo "Finished."

请配置执行权限和用户组和用户

centos6.5 安装git 最新版本

#安装git需要的库
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
yum install gcc perl-ExtUtils-MakeMaker

#删除自带的git
yum remove git

#切换到目录
cd /usr/src

#可以去看看需要的版本号
https://www.kernel.org/pub/software/scm/git/

#这里选择下载git2.7.0版本
wget https://www.kernel.org/pub/software/scm/git/git-2.7.0.tar.gz

#解压缩
tar -zxvf git-2.7.0.tar.gz

#切换到git-2.7.0目录
cd git-2.7.0

#开始验证
./configure

#编译安装
make prefix=/usr/local/git all
make prefix=/usr/local/git install
echo “export PATH=$PATH:/usr/local/git/bin” >> /etc/bashrc
source /etc/bashrc

#查看版本号
git –version

centos6.5 yum 安装php7,nginx1.8.1

#更新系统服务

yum -y update

#导入remi源

#64
rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

#32
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

#资源库
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

#创建nginx.repo源文件

touch /etc/yum.repos.d/nginx.repo

#打开源文件内容

vim /etc/yum.repos.d/nginx.repo

#编辑器源文件内容

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

 

#更新源

yum –enablerepo=remi -y update 

#安装服务 php70,mysql,nginx,php-fpm
yum -y –enablerepo=remi,remi-php70 install nginx php-fpm php-common

#安装PHP模块
yum -y –enablerepo=remi,remi-php70 install php-opcache php-pecl-apcu php-cli php-pear php-pdo php-mysqlnd php-pgsql php-pecl-mongodb php-pecl-redis php-pecl-memcache php-pecl-memcached php-gd php-mbstring php-mcrypt php-xml

#安装Mysql
yum -y install mysql mysql-server

#安装mysql扩展
yum -y install mysql-connector-odbc mysql-devel libdbi-dbd-mysql

#创建fastcgi.conf
touch /etc/nginx/fastcgi.conf

#打开fastcgi.conf
vim /etc/nginx/fastcgi.conf

#编辑fastcgi.conf

if ($request_filename ~* (.*)\.php) {
set $php_url $1;
}
if (!-e $php_url.php) {
return 403;
}
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with –enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

#打开nginx.conf (ps:我的nginx是最新文档版本1.8.1)
vim /etc/nginx/nginx.conf

#编辑以下内容

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 65535;

events
{
use epoll;
worker_connections 65535;
}

http
{
include /etc/nginx/mime.types;
default_type application/octet-stream;

server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;

sendfile on;
tcp_nopush on;

keepalive_timeout 15;

tcp_nodelay on;

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
gzip_disable msie6;
#limit_zone crawler $binary_remote_addr 10m;
log_format ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;
#access_log /var/log/nginx/access.log main;
include /etc/nginx/conf.d/*.conf;
}

#设置nginx 自启服务
/sbin/chkconfig –add nginx
/sbin/chkconfig nginx on

#nginx 启动
/sbin/service nginx start

#设置php-fpm 自启服务
/sbin/chkconfig –add php-fpm
/sbin/chkconfig php-fpm on

#php-fpm 启动
/sbin/service php-fpm start

#添加mysql 自启服务
/sbin/chkconfig –add mysqld
/sbin/chkconfig mysqld on

#mysql 启动
/sbin/service mysqld start

#设置MYSQL密码
mysqladmin -u root password ‘new passwd’
#打开mysql
mysql -u root -p
#删除test数据库
DROP DATABASE test;
#删除匿名帐户
DELETE FROM mysql.user WHERE user =”;
#重载权限
FLUSH PRIVILEGES;

#设置一个独立的nginx 虚拟主机配置
cd /etc/nginx/conf.d

#创建一条zmq.conf
touch zmq.conf

#打开zmq.conf
vim zmq.conf

#编辑以下内容,对应请修改需要的ROOT目录

server {
listen 80;
server_name Domain name
index index.html index.htm index.php;
root you in path
location ~ .*\.(php|php5|php7)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 1h;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
access_log you in url/you in name.log;
}

其余提示

php-fpm 需要配置相关的权限

nginx 执行的程序目录也需要配置权限

php写守护进程(Daemon)(转载)

PHP是否可以写守护进程?我觉得是可以的,业务不同,场景不同,产生的效果也不同,以下该文章很不错,特意转载过来

来源:http://blog.csdn.net/tengzhaorong/article/details/9764655

守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程是一种很有用的进程。php也可以实现守护进程的功能。

1、基本概念
进程每个进程都有一个父进程,子进程退出,父进程能得到子进程退出的状态。
进程组每个进程都属于一个进程组,每个进程组都有一个进程组号,该号等于该进程组组长的PID

2、守护编程要点
1. 在后台运行。
为避免挂起控制终端将Daemon放入后台执行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。 if($pid=pcntl_fork()) exit(0);//是父进程,结束父进程,子进程继续
2. 脱离控制终端,登录会话和进程组
有必要先介绍一下Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终 端。 控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长: posix_setsid();
说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。
3. 禁止进程重新打开控制终端
现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端: if($pid=pcntl_fork()) exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长)
4. 关闭打开的文件描述符
进程从创建它的父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。按如下方法关闭它们:
fclose(STDIN),fclose(STDOUT),fclose(STDERR)关闭标准输入输出与错误显示。
5. 改变当前工作目录
进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。对于需要转储核心,写运行日志的进程将工作目录改变到特定目录如chdir(“/”)
6. 重设文件创建掩模
进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:umask(0);
7. 处理SIGCHLD信号
处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影 响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。 signal(SIGCHLD,SIG_IGN);
这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不同,BSD4下必须显式等待子进程结束才能释放僵尸进程。google so “Linux 信号说明列表”

3、实例

< ?php /** *@author tengzhaorong@gmail.com *@date 2013-07-25 * 后台脚本控制类 */ class DaemonCommand{ private $info_dir="/tmp"; private $pid_file=""; private $terminate=false; //是否中断 private $workers_count=0; private $gc_enabled=null; private $workers_max=8; //最多运行8个进程 public function __construct($is_sington=false,$user='nobody',$output="/dev/null"){ $this->is_sington=$is_sington; //是否单例运行,单例运行会在tmp目录下建立一个唯一的PID
$this->user=$user;//设置运行的用户 默认情况下nobody
$this->output=$output; //设置输出的地方
$this->checkPcntl();
}
//检查环境是否支持pcntl支持
public function checkPcntl(){
if ( ! function_exists('pcntl_signal_dispatch')) {
// PHP < 5.3 uses ticks to handle signals instead of pcntl_signal_dispatch // call sighandler only every 10 ticks declare(ticks = 10); } // Make sure PHP has support for pcntl if ( ! function_exists('pcntl_signal')) { $message = 'PHP does not appear to be compiled with the PCNTL extension. This is neccesary for daemonization'; $this->_log($message);
throw new Exception($message);
}
//信号处理
pcntl_signal(SIGTERM, array(__CLASS__, "signalHandler"),false);
pcntl_signal(SIGINT, array(__CLASS__, "signalHandler"),false);
pcntl_signal(SIGQUIT, array(__CLASS__, "signalHandler"),false);

// Enable PHP 5.3 garbage collection
if (function_exists('gc_enable'))
{
gc_enable();
$this->gc_enabled = gc_enabled();
}
}

// daemon化程序
public function daemonize(){

global $stdin, $stdout, $stderr;
global $argv;

set_time_limit(0);

// 只允许在cli下面运行
if (php_sapi_name() != "cli"){
die("only run in command line mode\n");
}

// 只能单例运行
if ($this->is_sington==true){

$this->pid_file = $this->info_dir . "/" .__CLASS__ . "_" . substr(basename($argv[0]), 0, -4) . ".pid";
$this->checkPidfile();
}

umask(0); //把文件掩码清0

if (pcntl_fork() != 0){ //是父进程,父进程退出
exit();
}

posix_setsid();//设置新会话组长,脱离终端

if (pcntl_fork() != 0){ //是第一子进程,结束第一子进程
exit();
}

chdir("/"); //改变工作目录

$this->setUser($this->user) or die("cannot change owner");

//关闭打开的文件描述符
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);

$stdin = fopen($this->output, 'r');
$stdout = fopen($this->output, 'a');
$stderr = fopen($this->output, 'a');

if ($this->is_sington==true){
$this->createPidfile();
}

}

//--检测pid是否已经存在
public function checkPidfile(){

if (!file_exists($this->pid_file)){
return true;
}
$pid = file_get_contents($this->pid_file);
$pid = intval($pid);
if ($pid > 0 && posix_kill($pid, 0)){
$this->_log("the daemon process is already started");
}
else {
$this->_log("the daemon proces end abnormally, please check pidfile " . $this->pid_file);
}
exit(1);

}
//----创建pid
public function createPidfile(){

if (!is_dir($this->info_dir)){
mkdir($this->info_dir);
}
$fp = fopen($this->pid_file, 'w') or die("cannot create pid file");
fwrite($fp, posix_getpid());
fclose($fp);
$this->_log("create pid file " . $this->pid_file);
}

//设置运行的用户
public function setUser($name){

$result = false;
if (empty($name)){
return true;
}
$user = posix_getpwnam($name);
if ($user) {
$uid = $user['uid'];
$gid = $user['gid'];
$result = posix_setuid($uid);
posix_setgid($gid);
}
return $result;

}
//信号处理函数
public function signalHandler($signo){

switch($signo){

//用户自定义信号
case SIGUSR1: //busy
if ($this->workers_count < $this->workers_max){
$pid = pcntl_fork();
if ($pid > 0){
$this->workers_count ++;
}
}
break;
//子进程结束信号
case SIGCHLD:
while(($pid=pcntl_waitpid(-1, $status, WNOHANG)) > 0){
$this->workers_count --;
}
break;
//中断进程
case SIGTERM:
case SIGHUP:
case SIGQUIT:

$this->terminate = true;
break;
default:
return false;
}

}
/**
*开始开启进程
*$count 准备开启的进程数
*/
public function start($count=1){

$this->_log("daemon process is running now");
pcntl_signal(SIGCHLD, array(__CLASS__, "signalHandler"),false); // if worker die, minus children num
while (true) {
if (function_exists('pcntl_signal_dispatch')){

pcntl_signal_dispatch();
}

if ($this->terminate){
break;
}
$pid=-1;
if($this->workers_count< $count){ $pid=pcntl_fork(); } if($pid>0){

$this->workers_count++;

}elseif($pid==0){

// 这个符号表示恢复系统对信号的默认处理
pcntl_signal(SIGTERM, SIG_DFL);
pcntl_signal(SIGCHLD, SIG_DFL);
if(!empty($this->jobs)){
while($this->jobs['runtime']){
if(empty($this->jobs['argv'])){
call_user_func($this->jobs['function'],$this->jobs['argv']);
}else{
call_user_func($this->jobs['function']);
}
$this->jobs['runtime']--;
sleep(2);
}
exit();

}
return;

}else{

sleep(2);
}

}

$this->mainQuit();
exit(0);

}

//整个进程退出
public function mainQuit(){

if (file_exists($this->pid_file)){
unlink($this->pid_file);
$this->_log("delete pid file " . $this->pid_file);
}
$this->_log("daemon process exit now");
posix_kill(0, SIGKILL);
exit(0);
}

// 添加工作实例,目前只支持单个job工作
public function setJobs($jobs=array()){

if(!isset($jobs['argv'])||empty($jobs['argv'])){

$jobs['argv']="";

}
if(!isset($jobs['runtime'])||empty($jobs['runtime'])){

$jobs['runtime']=1;

}

if(!isset($jobs['function'])||empty($jobs['function'])){

$this->log("你必须添加运行的函数!");
}

$this->jobs=$jobs;

}
//日志处理
private function _log($message){
printf("%s\t%d\t%d\t%s\n", date("c"), posix_getpid(), posix_getppid(), $message);
}

}

demo code:


//调用方法1
$daemon=new DaemonCommand(true);
$daemon->daemonize();
$daemon->start(2);//开启2个子进程工作
work();

//调用方法2
$daemon=new DaemonCommand(true);
$daemon->daemonize();
//function 要运行的函数,argv运行函数的参数,runtime运行的次数
$daemon->addJobs(array('function'=>'work','argv'=>'','runtime'=>1000));
$daemon->start(2);//开启2个子进程工作

//具体功能的实现
function work(){
echo "测试1";
}

mac 配置golng开发环境

第一步:官网下载pkg包安装
默认路径:/usr/local/go

配置全局变量:

vim ~/.bash_profile

输入以下内容:

export GOROOT=/usr/local/go

export PATH=/usr/local/go/bin:$PATH

export GOPATH=你自己平时将go代码放置的地方

执行生效

source ~/. bash_profile

查看版本

go version