int *p[3] p是一个数组,此数组有3个元素,每个元素都是int*类型,也就是指向整型数据的指针类型。
int a=10,b=20,c=30;
int*p[3]={&a,&b,&c};
而int(*p)[3]中的p是一个指向数组的指针,此数组有3个int类型的元素。例如:
int a[3]={1,2,3}; 那么p就是指向这个数组a的指针。
int(*p)[3]=&a; // 这里赋值一定要用取地址符号。也就是取数组a的地址。
不可以这样赋值: int(*p)[3]=a; // error :类型不兼容。a本来是数组类型,是不可以赋值给int(*)[3]这个类型的。
但是这样是可以的int *p1=a; // ok 因为a可以隐式转换为int*类型,其值实际上就是数组第一个元素的地址,也就是&a[0]
*p[3] 这个是一个指针数组 它所代表的意思是每一个元素都相当于一个指针变量
而(*p)[3] p是一个指针变量,表示指向含有3个整型元素的一维数组
前者可以类似于二维数组 把它看成是由3个一维数组组成的 经常与字符串搭配使用 比较方便操作 把多个字符串放在一个指针数组中
后者是用来引用二维数组的 像a[2][3]这个二维数组 我们既可用指针来引用 又可用(*p)[3]来引用 一般使用(*p)[3
来源:http://zhidao.baidu.com/question/128144862.html
int a=10,b=20,c=30;
int*p[3]={&a,&b,&c};
而int(*p)[3]中的p是一个指向数组的指针,此数组有3个int类型的元素。例如:
int a[3]={1,2,3}; 那么p就是指向这个数组a的指针。
int(*p)[3]=&a; // 这里赋值一定要用取地址符号。也就是取数组a的地址。
不可以这样赋值: int(*p)[3]=a; // error :类型不兼容。a本来是数组类型,是不可以赋值给int(*)[3]这个类型的。
但是这样是可以的int *p1=a; // ok 因为a可以隐式转换为int*类型,其值实际上就是数组第一个元素的地址,也就是&a[0]
*p[3] 这个是一个指针数组 它所代表的意思是每一个元素都相当于一个指针变量
而(*p)[3] p是一个指针变量,表示指向含有3个整型元素的一维数组
前者可以类似于二维数组 把它看成是由3个一维数组组成的 经常与字符串搭配使用 比较方便操作 把多个字符串放在一个指针数组中
后者是用来引用二维数组的 像a[2][3]这个二维数组 我们既可用指针来引用 又可用(*p)[3]来引用 一般使用(*p)[3
#include <iostream.h>
int main()
{ int i,j;
int a[2][3]={3,4,5,6,7,8};
int *p[3] ;//表示存贮是3个整型变量地址;
int (*q)[3]; //表示指向3个整型数组元素的一维数组指针
//把第一行三个元素地址存放在p指针数组中
for( i=0;i<3;++i)
p[i]=&a[0][i];
//输出指针数组中地址所对应值
for( j=0;j<3;++j)
cout<< *p[j]<<" ";
cout<<endl;
q=a;//把数组a开始地址赋给指向一维数组q;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
cout<< *(*(q+i)+j)<<" "; //输出数组中元素
return 0;
}
int main()
{ int i,j;
int a[2][3]={3,4,5,6,7,8};
int *p[3] ;//表示存贮是3个整型变量地址;
int (*q)[3]; //表示指向3个整型数组元素的一维数组指针
//把第一行三个元素地址存放在p指针数组中
for( i=0;i<3;++i)
p[i]=&a[0][i];
//输出指针数组中地址所对应值
for( j=0;j<3;++j)
cout<< *p[j]<<" ";
cout<<endl;
q=a;//把数组a开始地址赋给指向一维数组q;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
cout<< *(*(q+i)+j)<<" "; //输出数组中元素
return 0;
}
来源:http://zhidao.baidu.com/question/128144862.html
最近awk用得比较多,于是简简单单记录一下。
awk非常的优秀,运行效率高,而且代码简单,对格式化的文本处理能力超强。基本上grep和sed能干的活awk全部都能干,而且干得更好。
先来一个很爽的例子:
文件a,统计文件a的第一列中是浮点数的行的浮点数的平均值。用awk来实现只需要一句话就可以搞定(当然,这个东东用python也可以很轻松的实现,只是无论如何都得新建一个文件;别妄想用bash shell来做,那可是浮点数!!!)
$cat a
1.021 33
1#.ll 44
2.53 6
ss 7
awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' a
niubility!
awk非常的优秀,运行效率高,而且代码简单,对格式化的文本处理能力超强。基本上grep和sed能干的活awk全部都能干,而且干得更好。
先来一个很爽的例子:
文件a,统计文件a的第一列中是浮点数的行的浮点数的平均值。用awk来实现只需要一句话就可以搞定(当然,这个东东用python也可以很轻松的实现,只是无论如何都得新建一个文件;别妄想用bash shell来做,那可是浮点数!!!)
$cat a
1.021 33
1#.ll 44
2.53 6
ss 7
awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' a
niubility!
[/diff]# awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' a
1.7755
1.7755
string fgets ( int $handle [, int $length ] )
从 handle 指向的文件中读取一行并返回长度最多为 length - 1 字节的字符串。碰到换行符(包括在返回值中)、EOF 或者已经读取了 length - 1 字节后停止(看先碰到那一种情况)。如果没有指定 length ,则默认为 1K,或者说 1024 字节。
bool feof ( resource $handle )
果传递的文件指针无效可能会陷入无限循环中,因为 EOF 不会返回 TRUE。
先上代码,正确的写法:
指针位置文件:line_number_mark.txt,需要读取N行的大文件:onlyQQFilteredByJack.txt
<?php
$num = 0;
$insert_num = 10; //insert amount every time.
if(file_exists('line_number_mark.txt'))
{
$num = trim(file_get_contents($rootPath . 'line_number_mark.txt'));
}
echo "pointer_num=".$num."\n";
$fp = fopen('./onlyQQFilteredByJack.txt', 'r');
fseek($fp, $num);
$i = 0;
while($i < $insert_num)
{
if(!feof($fp))
{
$data = fgets($fp);
$value = trim($data);
if(!empty($value))
{
$i++;
echo $value."\n";
}
}else
{
echo "out of the file's bindery,exit the while loop..\n";
$position = ftell($fp);
$flag = 1;//set flag means it's already end
break;//Break 退出循环
}
}
if($flag)
file_put_contents($rootPath . 'line_number_mark.txt', $position);
else
file_put_contents($rootPath . 'line_number_mark.txt', ftell($fp));
?>
指针的越位,错误的写法:
<?php
$num = 0;
$insert_num = 10; //insert amount every time.
if(file_exists($rootPath . 'line_number_mark.txt'))
{
$num = trim(file_get_contents($rootPath . 'line_number_mark.txt'));
}
echo "num=".$num."\n";
$fp = fopen($rootPath . 'onlyQQFilteredByJack.txt', 'r');
fseek($fp, $num);
echo ftell($fp)."\n";
if(feof($fp))
{
echo "Out of the file's bond\n";
exit();
}
$i = 0;
while($i < $insert_num)
{
$data = fgets($fp);//没fget一次,指针自动加一,后面ftell的值也是加一后的值,而在while下造成了越界,下次在来读取后在上面的if(feof($fp))出现传递的文件指针无效可能会陷入无限循环中,因为 EOF 不会返回 TRUE。
$value = trim($data);
if(!empty($value))
{
$i++;
echo $value."\n";
}
}
echo ftell($fp)."\n";
file_put_contents($rootPath . 'line_number_mark.txt', ftell($fp));
?>
阅读全文
从 handle 指向的文件中读取一行并返回长度最多为 length - 1 字节的字符串。碰到换行符(包括在返回值中)、EOF 或者已经读取了 length - 1 字节后停止(看先碰到那一种情况)。如果没有指定 length ,则默认为 1K,或者说 1024 字节。
bool feof ( resource $handle )
果传递的文件指针无效可能会陷入无限循环中,因为 EOF 不会返回 TRUE。
先上代码,正确的写法:
指针位置文件:line_number_mark.txt,需要读取N行的大文件:onlyQQFilteredByJack.txt
<?php
$num = 0;
$insert_num = 10; //insert amount every time.
if(file_exists('line_number_mark.txt'))
{
$num = trim(file_get_contents($rootPath . 'line_number_mark.txt'));
}
echo "pointer_num=".$num."\n";
$fp = fopen('./onlyQQFilteredByJack.txt', 'r');
fseek($fp, $num);
$i = 0;
while($i < $insert_num)
{
if(!feof($fp))
{
$data = fgets($fp);
$value = trim($data);
if(!empty($value))
{
$i++;
echo $value."\n";
}
}else
{
echo "out of the file's bindery,exit the while loop..\n";
$position = ftell($fp);
$flag = 1;//set flag means it's already end
break;//Break 退出循环
}
}
if($flag)
file_put_contents($rootPath . 'line_number_mark.txt', $position);
else
file_put_contents($rootPath . 'line_number_mark.txt', ftell($fp));
?>
指针的越位,错误的写法:
<?php
$num = 0;
$insert_num = 10; //insert amount every time.
if(file_exists($rootPath . 'line_number_mark.txt'))
{
$num = trim(file_get_contents($rootPath . 'line_number_mark.txt'));
}
echo "num=".$num."\n";
$fp = fopen($rootPath . 'onlyQQFilteredByJack.txt', 'r');
fseek($fp, $num);
echo ftell($fp)."\n";
if(feof($fp))
{
echo "Out of the file's bond\n";
exit();
}
$i = 0;
while($i < $insert_num)
{
$data = fgets($fp);//没fget一次,指针自动加一,后面ftell的值也是加一后的值,而在while下造成了越界,下次在来读取后在上面的if(feof($fp))出现传递的文件指针无效可能会陷入无限循环中,因为 EOF 不会返回 TRUE。
$value = trim($data);
if(!empty($value))
{
$i++;
echo $value."\n";
}
}
echo ftell($fp)."\n";
file_put_contents($rootPath . 'line_number_mark.txt', ftell($fp));
?>

1.Get多个参数示例:
2.Post多个参数示例:
2.Post多个参数示例:
CentOS xfce桌面上报错:
Failed to execute default Web Browser. input/output error。
13912:0329/111248.482393:ERROR:zygote_host_impl_linux.cc(90)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
13975:0329/111317.940689:ERROR:viz_main_impl.cc(188)] Exiting GPU process due to errors during initialization
14103:0329/111317.969178:ERROR:sandbox_linux.cc(377)] InitializeSandbox() called with multiple threads in process gpu-process.
google-chrome-stable --nogpgcheck
在桌面下面那个浏览器图标里选Chrome后,有一个笔:edit the currently selected iterm,加上:--nogpgcheck
/usr/bin/google-chrome-stable --no-sandbox %U #root帐户进桌面也有这个问题,直接将左边部分贴到里面即可。
Centos7.X之Chrome浏览器安装
1. 配置yum源
在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repo
#vim /ect/yum.repos.d/google-chrome.repo
写入如下内容:
Google官方源安装:
#yum -y install google-chrome-stable --nogpgcheck
来自:https://www.cnblogs.com/vae860514/p/8269002.html
Failed to execute default Web Browser. input/output error。
13912:0329/111248.482393:ERROR:zygote_host_impl_linux.cc(90)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
13975:0329/111317.940689:ERROR:viz_main_impl.cc(188)] Exiting GPU process due to errors during initialization
14103:0329/111317.969178:ERROR:sandbox_linux.cc(377)] InitializeSandbox() called with multiple threads in process gpu-process.
google-chrome-stable --nogpgcheck
在桌面下面那个浏览器图标里选Chrome后,有一个笔:edit the currently selected iterm,加上:--nogpgcheck
/usr/bin/google-chrome-stable --no-sandbox %U #root帐户进桌面也有这个问题,直接将左边部分贴到里面即可。
Centos7.X之Chrome浏览器安装
1. 配置yum源
在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repo
#vim /ect/yum.repos.d/google-chrome.repo
写入如下内容:
Google官方源安装:
#yum -y install google-chrome-stable --nogpgcheck
来自:https://www.cnblogs.com/vae860514/p/8269002.html
文件A和文件B分别存放着两组数,现要求出两组数的交集。
文件格式是每个数字占一行。
如,文件A为: 文件B为:
12 23
23 32
45 56
56
则交集应该为:
23
56
这里主要是学习diff这个命令的用途。
diff,比较文件,它是通过逐行比较两个文本文件的方式来找到两者不同的地方的。
输出结果中,以<开头的是属于第一个参数指定的文件的,以>开头的是属于第二个参数指定的文件的。
通过grep命令得到以<开头的即属于第一个文件但不属于第二个文件的行,并输出到一个临时文件中。
再以第一个文件与这个临时文件用diff来比较,同样方法,得到的就是两个文件的交集了。
要注意,比较的两个文件必须先进行排序。
如下:
[~/diff]# cat a.txt
12
23
45
56
[~/diff]# cat b.txt
23
32
56
[~/diff]# diff a.txt b.txt |grep -r "<" //管道输入到c.txt,去掉<
< 12
< 45
c.txt:
12
45
到C文件!
[~/diff]# diff a.txt c.txt |grep -r "<"
< 23
< 56
结果是:
23
56
代码页可以,如此啊:
改写测试成功,如下,加入dos2unix,很重要!
dos2unix diff.sh 这个命令运行一下。
亲自实践:
特别提醒:Linux与Windows文本格式之间的转化,Linux提供了两种文本格式相互转化的命令:dos2unix和unix2dos,dos2unix把"\r\n"转化成"\n",unix2dos把"\n"转化成"\r\n"。
不做如上操作,diff会出现问题!!!!!
diff antacardsort.txt anta_userqq_onlinesort.txt|grep "<"|awk -F"< " '{print $2}' > a.txt
sort a.txt >> aa.txt
diff antacardsort.txt asort.txt |grep "<"|awk -F"< " '{print $2}' > diffresultA.txt
diff antacardsort.txt anta_userqq_onlinesort.txt|grep ">"|awk -F"> " '{print $2}' > b.txt
sort b.txt >> bb.txt
diff anta_userqq_onlinesort.txt bb.txt |grep "<"|awk -F"< " '{print $2}' > diffresultB.txt
结果:
diffresultA.txt == diffresultB.txt
自己务必参考:http://www.jackxiang.com/post/1370/
来源:http://www.gdutbbs.com/thread-76831-1-1.html
文件格式是每个数字占一行。
如,文件A为: 文件B为:
12 23
23 32
45 56
56
则交集应该为:
23
56
这里主要是学习diff这个命令的用途。
diff,比较文件,它是通过逐行比较两个文本文件的方式来找到两者不同的地方的。
输出结果中,以<开头的是属于第一个参数指定的文件的,以>开头的是属于第二个参数指定的文件的。
通过grep命令得到以<开头的即属于第一个文件但不属于第二个文件的行,并输出到一个临时文件中。
再以第一个文件与这个临时文件用diff来比较,同样方法,得到的就是两个文件的交集了。
要注意,比较的两个文件必须先进行排序。
如下:
[~/diff]# cat a.txt
12
23
45
56
[~/diff]# cat b.txt
23
32
56
[~/diff]# diff a.txt b.txt |grep -r "<" //管道输入到c.txt,去掉<
< 12
< 45
c.txt:
12
45
到C文件!
[~/diff]# diff a.txt c.txt |grep -r "<"
< 23
< 56
结果是:
23
56
代码页可以,如此啊:
#######################################
# author:hjack
# Date:2006.7.16
# function:找两个文件中数的交集
# usage:intersection file1 file2
# History:
#######################################
usage(){
echo "Usage:$0 file1 file2"
exit 1;
}
testInput(){
REQUESTARG=2
if [ $# -ne $REQUESTARG ]; then
Usage "$@"
fi
}
getIntersection(){
seed=`date +%s`
sort $1 -un > /tmp/$1.$seed
sort $2 -un > /tmp/$2.$seed
diff /tmp/$1.$seed /tmp/$2.$seed | grep ^\< | awk '{print $2}' > /tmp/$1.$seed.only
diff /tmp/$1.$seed /tmp/$1.$seed.only | grep ^\< | awk '{print $2}'
}
main(){
testInput "$@"
getIntersection "$@"
}
main "$@"
# author:hjack
# Date:2006.7.16
# function:找两个文件中数的交集
# usage:intersection file1 file2
# History:
#######################################
usage(){
echo "Usage:$0 file1 file2"
exit 1;
}
testInput(){
REQUESTARG=2
if [ $# -ne $REQUESTARG ]; then
Usage "$@"
fi
}
getIntersection(){
seed=`date +%s`
sort $1 -un > /tmp/$1.$seed
sort $2 -un > /tmp/$2.$seed
diff /tmp/$1.$seed /tmp/$2.$seed | grep ^\< | awk '{print $2}' > /tmp/$1.$seed.only
diff /tmp/$1.$seed /tmp/$1.$seed.only | grep ^\< | awk '{print $2}'
}
main(){
testInput "$@"
getIntersection "$@"
}
main "$@"
改写测试成功,如下,加入dos2unix,很重要!
#######################################
# author:hjack
# Date:2006.7.16
# function:找两个文件中数的交集
# usage:intersection file1 file2
# History:
#######################################
usage(){
echo "Usage:$0 file1 file2"
exit 1;
}
testInput(){
REQUESTARG=2
if [ $# -ne $REQUESTARG ]; then
Usage "$@"
fi
}
getIntersection(){
seed=`date +%s`
dos2unix $1
dos2unix $2
sort $1 -un > /tmp/$1.$seed
sort $2 -un > /tmp/$2.$seed
diff /tmp/$1.$seed /tmp/$2.$seed | grep ^\< | awk '{print $2}' > /tmp/$1.$seed.only
diff /tmp/$1.$seed /tmp/$1.$seed.only | grep ^\< | awk '{print $2}'
}
main(){
testInput "$@"
getIntersection "$@"
}
main "$@"
# author:hjack
# Date:2006.7.16
# function:找两个文件中数的交集
# usage:intersection file1 file2
# History:
#######################################
usage(){
echo "Usage:$0 file1 file2"
exit 1;
}
testInput(){
REQUESTARG=2
if [ $# -ne $REQUESTARG ]; then
Usage "$@"
fi
}
getIntersection(){
seed=`date +%s`
dos2unix $1
dos2unix $2
sort $1 -un > /tmp/$1.$seed
sort $2 -un > /tmp/$2.$seed
diff /tmp/$1.$seed /tmp/$2.$seed | grep ^\< | awk '{print $2}' > /tmp/$1.$seed.only
diff /tmp/$1.$seed /tmp/$1.$seed.only | grep ^\< | awk '{print $2}'
}
main(){
testInput "$@"
getIntersection "$@"
}
main "$@"
dos2unix diff.sh 这个命令运行一下。
亲自实践:
特别提醒:Linux与Windows文本格式之间的转化,Linux提供了两种文本格式相互转化的命令:dos2unix和unix2dos,dos2unix把"\r\n"转化成"\n",unix2dos把"\n"转化成"\r\n"。
不做如上操作,diff会出现问题!!!!!
diff antacardsort.txt anta_userqq_onlinesort.txt|grep "<"|awk -F"< " '{print $2}' > a.txt
sort a.txt >> aa.txt
diff antacardsort.txt asort.txt |grep "<"|awk -F"< " '{print $2}' > diffresultA.txt
diff antacardsort.txt anta_userqq_onlinesort.txt|grep ">"|awk -F"> " '{print $2}' > b.txt
sort b.txt >> bb.txt
diff anta_userqq_onlinesort.txt bb.txt |grep "<"|awk -F"< " '{print $2}' > diffresultB.txt
diff antacardsort.txt asort.txt |grep ^\< | awk '{print $2}'
和
diff antacardsort.txt asort.txt |grep "<"|awk -F"< " '{print $2}'
一个意思!
和
diff antacardsort.txt asort.txt |grep "<"|awk -F"< " '{print $2}'
一个意思!
结果:
diffresultA.txt == diffresultB.txt
自己务必参考:http://www.jackxiang.com/post/1370/
来源:http://www.gdutbbs.com/thread-76831-1-1.html
写一个表单提交用到图片:两种代码。
会发生表单提交两次的现象,经常会造成表单元素被重复提交,数据库被写入异常!!
<img src="xxx.gif" onclick="return dosubmit();">
第二种则正常!!
原因::HTML 中 image的描述是“创建一个图像控件,该控件单击后将导致表单立即被提交。”。
请 尽量 少用<input type="image">以免造成不必要的异常!!!
<input type="image"的情况如何验证:
在对一个表单(form)进行客户端检验的时候,我们已经习惯了<form onsubmit=”return check()”>这样的形式,如果表单没有通过验证,在check函数中return false就会阻止表单的提交了。
来源:http://wxinpeng.javaeye.com/blog/209017
<input type="image" src="xxx.gif" onclick="return dosubmit();">
会发生表单提交两次的现象,经常会造成表单元素被重复提交,数据库被写入异常!!
<img src="xxx.gif" onclick="return dosubmit();">
第二种则正常!!
原因::HTML 中 image的描述是“创建一个图像控件,该控件单击后将导致表单立即被提交。”。
请 尽量 少用<input type="image">以免造成不必要的异常!!!
<input type="image"的情况如何验证:
在对一个表单(form)进行客户端检验的时候,我们已经习惯了<form onsubmit=”return check()”>这样的形式,如果表单没有通过验证,在check函数中return false就会阻止表单的提交了。
来源:http://wxinpeng.javaeye.com/blog/209017
apache并发数调整 收藏
阅读全文

摘要
本文介绍通过mod_limitipconn模块来限制apache的并发连接数的详细方法。
--------------------------------------------------------------------------------
By 风过留枫, 出处:Linux技术中坚站 冷风
下载mod_limitipconn.c
http://dominia.org/djao/limit/mod_limitipconn-0.04.tar.gz
http://dominia.org/djao/limit/mod_limitipconn-0.04-1.i386.rpm
(proxy client detection feature not enabled)
http://dominia.org/djao/limit/mod_limitipconn-0.04-1.src.rpm
我用的是tar包下载的是mod_limitipconn-0.04.tar.gz,(该模块已经可以支持apache2)在服务器上执行# wget http://dominia.org/djao/limit/mod_limitipconn-0.04.tar.gz 下载到本地
然后执行下面的命令编译安装.我的apache位于/usr/local/apache目录
解压缩:
[root@ns chenlf]# tar zxvf mod_limitipconn-0.04.tar.gz
mod_limitipconn-0.04/
mod_limitipconn-0.04/Makefile
mod_limitipconn-0.04/README
mod_limitipconn-0.04/apachesrc.diff
mod_limitipconn-0.04/mod_limitipconn.c
mod_limitipconn-0.04/ChangeLog
编译安装:
[root@ns chenlf]# cd mod_limitipconn-0.04
[root@ns mod_limitipconn-0.04]# ls
apachesrc.diff ChangeLog Makefile
mod_limitipconn.c README
[root@ns mod_limitipconn-0.04]
# /usr/local/apache/bin/apxs -c -i -a mod_limitipconn.c
gcc -DLINUX=22 -I/usr/include/db1 -fpic -DSHARED_MODULE -I
/usr/local/apache/include -c mod_limitipconn.c
gcc -shared -o mod_limitipconn.so mod_limitipconn.o
[activating module `limitipconn' in /usr/local
/apache/conf/httpd.conf]
cp mod_limitipconn.so /usr/local/apache/libexec/mod_limitipconn.so
chmod 755 /usr/local/apache/libexec/mod_limitipconn.so
cp /usr/local/apache/conf/httpd.conf
/usr/local/apache/conf/httpd.conf.bak
cp /usr/local/apache/conf/httpd.conf.new
/usr/local/apache/conf/httpd.conf
rm /usr/local/apache/conf/httpd.conf.new
修改配置文件:
1全局控制:
在httpd.conf加上以下几行:
< IfModule mod_limitipconn.c >;
< Location / >; # 所有虚拟主机的/目录
MaxConnPerIP 3 # 每IP只允许3个并发连接
NoIPLimit image/* # 对图片不做IP限制
< /Location >;
< Location /mp3 >; # 所有主机的/mp3目录
MaxConnPerIP 1 # 每IP只允许一个连接请求
OnlyIPLimit audio/mpeg video # 该限制只对视频和音频格式的文件
< /Location >;
< /IfModule >;
2 局部限制,你也可以在虚拟主机的配置文件里设置IP限制,方法是完全一样:
< VirtualHost xx.xxx.xx.xx >;
ServerAdmin chenlf@chinalinuxpub.com
DocumentRoot /home/my
ServerName www.my.com
< IfModule mod_limitipconn.c >;
< Location / >; # 所有虚拟主机的/目录
MaxConnPerIP 5 # 每IP只允许3个并发连接
NoIPLimit image/* # 对图片不做IP限制
< /Location >;
< Location /mp3 >; # 所有主机的/mp3目录
MaxConnPerIP 2 # 每IP只允许一个连接请求
OnlyIPLimit audio/mpeg video # 该限制只对视频和音频格式的文件
< /Location >;
< /IfModule >;
ErrorLog /home/my/logs/error_log
CustomLog /home/my/logs/access_log common
< /VirtualHost >;
3 此外必须将apache的ExtendedStatus设置为ON.在httpd.conf找到
# ExtendedStatus On
去掉前面的注释即可
好了,全部配置结束,重起apache就可以生效了
(完)
本文介绍通过mod_limitipconn模块来限制apache的并发连接数的详细方法。
--------------------------------------------------------------------------------
By 风过留枫, 出处:Linux技术中坚站 冷风
下载mod_limitipconn.c
http://dominia.org/djao/limit/mod_limitipconn-0.04.tar.gz
http://dominia.org/djao/limit/mod_limitipconn-0.04-1.i386.rpm
(proxy client detection feature not enabled)
http://dominia.org/djao/limit/mod_limitipconn-0.04-1.src.rpm
我用的是tar包下载的是mod_limitipconn-0.04.tar.gz,(该模块已经可以支持apache2)在服务器上执行# wget http://dominia.org/djao/limit/mod_limitipconn-0.04.tar.gz 下载到本地
然后执行下面的命令编译安装.我的apache位于/usr/local/apache目录
解压缩:
[root@ns chenlf]# tar zxvf mod_limitipconn-0.04.tar.gz
mod_limitipconn-0.04/
mod_limitipconn-0.04/Makefile
mod_limitipconn-0.04/README
mod_limitipconn-0.04/apachesrc.diff
mod_limitipconn-0.04/mod_limitipconn.c
mod_limitipconn-0.04/ChangeLog
编译安装:
[root@ns chenlf]# cd mod_limitipconn-0.04
[root@ns mod_limitipconn-0.04]# ls
apachesrc.diff ChangeLog Makefile
mod_limitipconn.c README
[root@ns mod_limitipconn-0.04]
# /usr/local/apache/bin/apxs -c -i -a mod_limitipconn.c
gcc -DLINUX=22 -I/usr/include/db1 -fpic -DSHARED_MODULE -I
/usr/local/apache/include -c mod_limitipconn.c
gcc -shared -o mod_limitipconn.so mod_limitipconn.o
[activating module `limitipconn' in /usr/local
/apache/conf/httpd.conf]
cp mod_limitipconn.so /usr/local/apache/libexec/mod_limitipconn.so
chmod 755 /usr/local/apache/libexec/mod_limitipconn.so
cp /usr/local/apache/conf/httpd.conf
/usr/local/apache/conf/httpd.conf.bak
cp /usr/local/apache/conf/httpd.conf.new
/usr/local/apache/conf/httpd.conf
rm /usr/local/apache/conf/httpd.conf.new
修改配置文件:
1全局控制:
在httpd.conf加上以下几行:
< IfModule mod_limitipconn.c >;
< Location / >; # 所有虚拟主机的/目录
MaxConnPerIP 3 # 每IP只允许3个并发连接
NoIPLimit image/* # 对图片不做IP限制
< /Location >;
< Location /mp3 >; # 所有主机的/mp3目录
MaxConnPerIP 1 # 每IP只允许一个连接请求
OnlyIPLimit audio/mpeg video # 该限制只对视频和音频格式的文件
< /Location >;
< /IfModule >;
2 局部限制,你也可以在虚拟主机的配置文件里设置IP限制,方法是完全一样:
< VirtualHost xx.xxx.xx.xx >;
ServerAdmin chenlf@chinalinuxpub.com
DocumentRoot /home/my
ServerName www.my.com
< IfModule mod_limitipconn.c >;
< Location / >; # 所有虚拟主机的/目录
MaxConnPerIP 5 # 每IP只允许3个并发连接
NoIPLimit image/* # 对图片不做IP限制
< /Location >;
< Location /mp3 >; # 所有主机的/mp3目录
MaxConnPerIP 2 # 每IP只允许一个连接请求
OnlyIPLimit audio/mpeg video # 该限制只对视频和音频格式的文件
< /Location >;
< /IfModule >;
ErrorLog /home/my/logs/error_log
CustomLog /home/my/logs/access_log common
< /VirtualHost >;
3 此外必须将apache的ExtendedStatus设置为ON.在httpd.conf找到
# ExtendedStatus On
去掉前面的注释即可
好了,全部配置结束,重起apache就可以生效了
(完)
一大早,一个年轻的程序员问大师:
“我准备写一些单元测试用例。代码覆盖率应该达到多少为好?”
大师回答道:
“不要考虑代码覆盖率,只要写出一些好的测试用例即可。”
年轻的程序员很高兴,鞠躬,离去。
之后没多久,第二个程序员问了大师同样的问题。
大师指着一锅烧沸的水说:
“我应该往这个锅里放多少米?”
这个程序员看起来被难住了,回答道:
“我怎么会有答案?这取决于要给多少人吃,他们饿不饿,有什么菜,你有多少米,等等。”
“完全正确,” 大师说。
第二个程序员很高兴,鞠躬,离去。
末了,来了第三个程序员问了大师同样的关于代码覆盖率的问题。
“百分之八十,不能少!” 大师一拳锤在桌子上,用严厉的口气回答道。
第三个程序员很高兴,鞠躬,离去。
回复完这个之后,一个年轻的实习生走到大师身边:
“大师,今天我无意中听到了你对同一个代码覆盖率问题给出了三个不同的答案。为什么?”
大师从椅子上站起来:
“给我泡点新茶,我们聊聊这个。”
当杯子里倒满了冒着热气的绿茶后,大师开始说:
“这第一个程序员是个新手,刚刚开始学测试。目前他有大量的程序都没有测试用例。他有很长的路要走;现在对他要求代码覆盖率只会打击他,没有什么用处。最好是让他慢慢的学会写一些测试用例,测试一下。他可以以后再考虑代码覆盖率。”
“而这第二个程序员,不论对编程还是测试都是十分的有经验。我以问作答,问她应该往锅里放多少米,使她明白决定测试用例多少的因素有很多,她比我更知道这些因素——毕竟是她自己的代码。对这个问题没有一个简单的、直接的答案。以她的聪明完全能明白这个道理,正确的完成任务。”
“我明白了,” 年轻的实习生说, “但是如果没有一个简单直接的答案,那你为什么告诉第三个程序员‘百分之八十,不能少’呢?”
大师笑的前仰后合,绿茶都喷了出来。
“这第三个程序员只想得到一个简单的答案——即使根本没有简单的答案 … 而且即使有答案她也不会按答案做。”
年轻的实习生和头发斑白的大师在沉思中喝完茶。
“我准备写一些单元测试用例。代码覆盖率应该达到多少为好?”
大师回答道:
“不要考虑代码覆盖率,只要写出一些好的测试用例即可。”
年轻的程序员很高兴,鞠躬,离去。
之后没多久,第二个程序员问了大师同样的问题。
大师指着一锅烧沸的水说:
“我应该往这个锅里放多少米?”
这个程序员看起来被难住了,回答道:
“我怎么会有答案?这取决于要给多少人吃,他们饿不饿,有什么菜,你有多少米,等等。”
“完全正确,” 大师说。
第二个程序员很高兴,鞠躬,离去。
末了,来了第三个程序员问了大师同样的关于代码覆盖率的问题。
“百分之八十,不能少!” 大师一拳锤在桌子上,用严厉的口气回答道。
第三个程序员很高兴,鞠躬,离去。
回复完这个之后,一个年轻的实习生走到大师身边:
“大师,今天我无意中听到了你对同一个代码覆盖率问题给出了三个不同的答案。为什么?”
大师从椅子上站起来:
“给我泡点新茶,我们聊聊这个。”
当杯子里倒满了冒着热气的绿茶后,大师开始说:
“这第一个程序员是个新手,刚刚开始学测试。目前他有大量的程序都没有测试用例。他有很长的路要走;现在对他要求代码覆盖率只会打击他,没有什么用处。最好是让他慢慢的学会写一些测试用例,测试一下。他可以以后再考虑代码覆盖率。”
“而这第二个程序员,不论对编程还是测试都是十分的有经验。我以问作答,问她应该往锅里放多少米,使她明白决定测试用例多少的因素有很多,她比我更知道这些因素——毕竟是她自己的代码。对这个问题没有一个简单的、直接的答案。以她的聪明完全能明白这个道理,正确的完成任务。”
“我明白了,” 年轻的实习生说, “但是如果没有一个简单直接的答案,那你为什么告诉第三个程序员‘百分之八十,不能少’呢?”
大师笑的前仰后合,绿茶都喷了出来。
“这第三个程序员只想得到一个简单的答案——即使根本没有简单的答案 … 而且即使有答案她也不会按答案做。”
年轻的实习生和头发斑白的大师在沉思中喝完茶。
MYSQL导出一个SQL后:
DELIMITER $$
DROP TRIGGER IF EXISTS `updateegopriceondelete`$$
CREATE
TRIGGER `updateegopriceondelete` AFTER DELETE ON `customerinfo`
FOR EACH ROW BEGIN
DELETE FROM egoprice WHERE customerId=OLD.customerId;
END$$
DELIMITER ;
其中DELIMITER 定好结束符为"$$", 然后最后又定义为";", MYSQL的默认结束符为";".
阅读全文
DELIMITER $$
DROP TRIGGER IF EXISTS `updateegopriceondelete`$$
CREATE
TRIGGER `updateegopriceondelete` AFTER DELETE ON `customerinfo`
FOR EACH ROW BEGIN
DELETE FROM egoprice WHERE customerId=OLD.customerId;
END$$
DELIMITER ;
其中DELIMITER 定好结束符为"$$", 然后最后又定义为";", MYSQL的默认结束符为";".

如何进行实际分区
看看分区的实际效果吧。我们建立几个同样的MyISAM引擎的表,包含日期敏感的数据,但只对其中一个分区。分区的表(表名为part_tab)我们采用Range范围分区模式,通过年份进行分区:
注意到了这里的最后一行吗?这里把不属于前面年度划分的年份范围都包含了,这样才能保证数据不会出错,大家以后要记住啊,不然数据库无缘无故出错你就爽了。那下面我们建立没有分区的表(表名为no_part_tab):
下面咱写一个存储过程(感谢Peter Gulutzan给的代码,如果大家需要Peter Gulutzan的存储过程教程的中文翻译也可以跟我要,chenpengyi◎gmail.com),它能向咱刚才建立的已分区的表中平均的向每个分区插入共8百万条不同的数据。填满后,咱就给没分区的克隆表中插入相同的数据:
mysql> delimiter //
mysql> CREATE PROCEDURE load_part_tab()
-> begin
-> declare v int default 0;
-> while v < 8000000
-> do
-> insert into part_tab
-> values (v,'testing partitions',adddate('1995-01-01',(rand(v)*36520) mod 3652));
-> set v = v + 1;
-> end while;
-> end
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call load_part_tab();
Query OK, 1 row affected (8 min 17.75 sec)
mysql> insert into no_part_tab select * from part_tab;
Query OK, 8000000 rows affected (51.59 sec)
Records: 8000000 Duplicates: 0 Warnings: 0
表都准备好了。咱开始对这两表中的数据进行简单的范围查询吧。先分区了的,后没分区的,跟着有执行过程解析(MySQL Explain命令解析器),可以看到MySQL做了什么:
mysql> select count(*) from no_part_tab where
-> c3 > date '1995-01-01' and c3 < date '1995-12-31';
+----------+
| count(*) |
+----------+
| 795181 |
+----------+
1 row in set (38.30 sec)
mysql> select count(*) from part_tab where
-> c3 > date '1995-01-01' and c3 < date '1995-12-31';
+----------+
| count(*) |
+----------+
| 795181 |
+----------+
1 row in set (3.88 sec)
mysql> explain select count(*) from no_part_tab where
-> c3 > date '1995-01-01' and c3 < date '1995-12-31'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: no_part_tab
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 8000000
Extra: Using where
1 row in set (0.00 sec)
mysql> explain partitions select count(*) from part_tab where
-> c3 > date '1995-01-01' and c3 < date '1995-12-31'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: part_tab
partitions: p1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 798458
Extra: Using where
1 row in set (0.00 sec)
从上面结果可以容易看出,设计恰当表分区能比非分区的减少90%的响应时间。而命令解析Explain程序也告诉我们在对已分区的表的查询过程中仅对第一个分区进行了扫描,其他都跳过了。
看看分区的实际效果吧。我们建立几个同样的MyISAM引擎的表,包含日期敏感的数据,但只对其中一个分区。分区的表(表名为part_tab)我们采用Range范围分区模式,通过年份进行分区:
REATE TABLE part_tab(
c1 int default NULL ,
c2 varchar( 30 ) default NULL ,
c3 date default NULL
) ENGINE = MYISAM PARTITION BY RANGE (
year( c3 )
)(
PARTITION p0 VALUES LESS THAN( 1995 ) , PARTITION p1
VALUES LESS THAN( 1996 ) , PARTITION p2
VALUES LESS THAN( 1997 ) , PARTITION p3
VALUES LESS THAN( 1998 ) , PARTITION p4
VALUES LESS THAN( 1999 ) , PARTITION p5
VALUES LESS THAN( 2000 ) , PARTITION p6
VALUES LESS THAN( 2001 ) , PARTITION p7
VALUES LESS THAN( 2002 ) , PARTITION p8
VALUES LESS THAN( 2003 ) , PARTITION p9
VALUES LESS THAN( 2004 ) , PARTITION p10
VALUES LESS THAN( 2010 ) , PARTITION p11
VALUES LESS THAN MAXVALUE
);
c1 int default NULL ,
c2 varchar( 30 ) default NULL ,
c3 date default NULL
) ENGINE = MYISAM PARTITION BY RANGE (
year( c3 )
)(
PARTITION p0 VALUES LESS THAN( 1995 ) , PARTITION p1
VALUES LESS THAN( 1996 ) , PARTITION p2
VALUES LESS THAN( 1997 ) , PARTITION p3
VALUES LESS THAN( 1998 ) , PARTITION p4
VALUES LESS THAN( 1999 ) , PARTITION p5
VALUES LESS THAN( 2000 ) , PARTITION p6
VALUES LESS THAN( 2001 ) , PARTITION p7
VALUES LESS THAN( 2002 ) , PARTITION p8
VALUES LESS THAN( 2003 ) , PARTITION p9
VALUES LESS THAN( 2004 ) , PARTITION p10
VALUES LESS THAN( 2010 ) , PARTITION p11
VALUES LESS THAN MAXVALUE
);
注意到了这里的最后一行吗?这里把不属于前面年度划分的年份范围都包含了,这样才能保证数据不会出错,大家以后要记住啊,不然数据库无缘无故出错你就爽了。那下面我们建立没有分区的表(表名为no_part_tab):
CREATE TABLE no_part_tab(
c1 int( 11 ) default NULL ,
c2 varchar( 30 ) default NULL ,
c3 date default NULL
) ENGINE = MYISAM ;
c1 int( 11 ) default NULL ,
c2 varchar( 30 ) default NULL ,
c3 date default NULL
) ENGINE = MYISAM ;
下面咱写一个存储过程(感谢Peter Gulutzan给的代码,如果大家需要Peter Gulutzan的存储过程教程的中文翻译也可以跟我要,chenpengyi◎gmail.com),它能向咱刚才建立的已分区的表中平均的向每个分区插入共8百万条不同的数据。填满后,咱就给没分区的克隆表中插入相同的数据:
mysql> delimiter //
mysql> CREATE PROCEDURE load_part_tab()
-> begin
-> declare v int default 0;
-> while v < 8000000
-> do
-> insert into part_tab
-> values (v,'testing partitions',adddate('1995-01-01',(rand(v)*36520) mod 3652));
-> set v = v + 1;
-> end while;
-> end
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call load_part_tab();
Query OK, 1 row affected (8 min 17.75 sec)
mysql> insert into no_part_tab select * from part_tab;
Query OK, 8000000 rows affected (51.59 sec)
Records: 8000000 Duplicates: 0 Warnings: 0
表都准备好了。咱开始对这两表中的数据进行简单的范围查询吧。先分区了的,后没分区的,跟着有执行过程解析(MySQL Explain命令解析器),可以看到MySQL做了什么:
mysql> select count(*) from no_part_tab where
-> c3 > date '1995-01-01' and c3 < date '1995-12-31';
+----------+
| count(*) |
+----------+
| 795181 |
+----------+
1 row in set (38.30 sec)
mysql> select count(*) from part_tab where
-> c3 > date '1995-01-01' and c3 < date '1995-12-31';
+----------+
| count(*) |
+----------+
| 795181 |
+----------+
1 row in set (3.88 sec)
mysql> explain select count(*) from no_part_tab where
-> c3 > date '1995-01-01' and c3 < date '1995-12-31'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: no_part_tab
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 8000000
Extra: Using where
1 row in set (0.00 sec)
mysql> explain partitions select count(*) from part_tab where
-> c3 > date '1995-01-01' and c3 < date '1995-12-31'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: part_tab
partitions: p1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 798458
Extra: Using where
1 row in set (0.00 sec)
从上面结果可以容易看出,设计恰当表分区能比非分区的减少90%的响应时间。而命令解析Explain程序也告诉我们在对已分区的表的查询过程中仅对第一个分区进行了扫描,其他都跳过了。