2009年7月16日
**
* <pre>
* Title: HttpRequestProxy.java
* Project: HP-Common
* Type: com.hengpeng.common.web.HttpRequestProxy
* Author: benl
* Create: 2007-7-3 上午03:07:07
* Copyright: Copyright (c) 2007
* Company:
* <pre>
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.log4j.Logger;
/**
* <pre>
* HTTP请求代理类
* </pre>
*
* @author benl
* @version 1.0, 2007-7-3
*/
public class HttpRequestProxy
{
/**
* 连接超时
*/
private static int connectTimeOut = 5000;
/**
* 读取数据超时
*/
private static int readTimeOut = 10000;
/**
* 请求编码
*/
private static String requestEncoding = "GBK";
private static Logger logger = Logger.getLogger(HttpRequestProxy.class);
/**
* <pre>
* 发送带参数的GET的HTTP请求
* </pre>
*
* @param reqUrl HTTP请求URL
* @param parameters 参数映射表
* @return HTTP响应的字符串
*/
public static String doGet(String reqUrl, Map parameters,
String recvEncoding)
{
HttpURLConnection url_con = null;
String responseContent = null;
try
{
StringBuffer params = new StringBuffer();
for (Iterator iter = parameters.entrySet().iterator(); iter
.hasNext();)
{
Entry element = (Entry) iter.next();
params.append(element.getKey().toString());
params.append("=");
params.append(URLEncoder.encode(element.getValue().toString(),
HttpRequestProxy.requestEncoding));
params.append("&");
}
if (params.length() > 0)
{
params = params.deleteCharAt(params.length() - 1);
}
URL url = new URL(reqUrl);
url_con = (HttpURLConnection) url.openConnection();
url_con.setRequestMethod("GET");
System.setProperty("sun.net.client.defaultConnectTimeout", String
.valueOf(HttpRequestProxy.connectTimeOut));// (单位:毫秒)jdk1.4换成这个,连接超时
System.setProperty("sun.net.client.defaultReadTimeout", String
.valueOf(HttpRequestProxy.readTimeOut)); // (单位:毫秒)jdk1.4换成这个,读操作超时
// url_con.setConnectTimeout(5000);//(单位:毫秒)jdk
// 1.5换成这个,连接超时
// url_con.setReadTimeout(5000);//(单位:毫秒)jdk 1.5换成这个,读操作超时
url_con.setDoOutput(true);
byte[] b = params.toString().getBytes();
url_con.getOutputStream().write(b, 0, b.length);
url_con.getOutputStream().flush();
url_con.getOutputStream().close();
InputStream in = url_con.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(in,
recvEncoding));
String tempLine = rd.readLine();
StringBuffer temp = new StringBuffer();
String crlf=System.getProperty("line.separator");
while (tempLine != null)
{
temp.append(tempLine);
temp.append(crlf);
tempLine = rd.readLine();
}
responseContent = temp.toString();
rd.close();
in.close();
}
catch (IOException e)
{
logger.error("网络故障", e);
}
finally
{
if (url_con != null)
{
url_con.disconnect();
}
}
return responseContent;
}
/**
* <pre>
* 发送不带参数的GET的HTTP请求
* </pre>
*
* @param reqUrl HTTP请求URL
* @return HTTP响应的字符串
*/
public static String doGet(String reqUrl, String recvEncoding)
{
HttpURLConnection url_con = null;
String responseContent = null;
try
{
StringBuffer params = new StringBuffer();
String queryUrl = reqUrl;
int paramIndex = reqUrl.indexOf("?");
if (paramIndex > 0)
{
queryUrl = reqUrl.substring(0, paramIndex);
String parameters = reqUrl.substring(paramIndex + 1, reqUrl
.length());
String[] paramArray = parameters.split("&");
for (int i = 0; i < paramArray.length; i++)
{
String string = paramArray[i];
int index = string.indexOf("=");
if (index > 0)
{
String parameter = string.substring(0, index);
String value = string.substring(index + 1, string
.length());
params.append(parameter);
params.append("=");
params.append(URLEncoder.encode(value,
HttpRequestProxy.requestEncoding));
params.append("&");
}
}
params = params.deleteCharAt(params.length() - 1);
}
URL url = new URL(queryUrl);
url_con = (HttpURLConnection) url.openConnection();
url_con.setRequestMethod("GET");
System.setProperty("sun.net.client.defaultConnectTimeout", String
.valueOf(HttpRequestProxy.connectTimeOut));// (单位:毫秒)jdk1.4换成这个,连接超时
System.setProperty("sun.net.client.defaultReadTimeout", String
.valueOf(HttpRequestProxy.readTimeOut)); // (单位:毫秒)jdk1.4换成这个,读操作超时
// url_con.setConnectTimeout(5000);//(单位:毫秒)jdk
// 1.5换成这个,连接超时
// url_con.setReadTimeout(5000);//(单位:毫秒)jdk 1.5换成这个,读操作超时
url_con.setDoOutput(true);
byte[] b = params.toString().getBytes();
url_con.getOutputStream().write(b, 0, b.length);
url_con.getOutputStream().flush();
url_con.getOutputStream().close();
InputStream in = url_con.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(in,
recvEncoding));
String tempLine = rd.readLine();
StringBuffer temp = new StringBuffer();
String crlf=System.getProperty("line.separator");
while (tempLine != null)
{
temp.append(tempLine);
temp.append(crlf);
tempLine = rd.readLine();
}
responseContent = temp.toString();
rd.close();
in.close();
}
catch (IOException e)
{
logger.error("网络故障", e);
}
finally
{
if (url_con != null)
{
url_con.disconnect();
}
}
return responseContent;
}
/**
* <pre>
* 发送带参数的POST的HTTP请求
* </pre>
*
* @param reqUrl HTTP请求URL
* @param parameters 参数映射表
* @return HTTP响应的字符串
*/
public static String doPost(String reqUrl, Map parameters,
String recvEncoding)
{
HttpURLConnection url_con = null;
String responseContent = null;
try
{
StringBuffer params = new StringBuffer();
for (Iterator iter = parameters.entrySet().iterator(); iter
.hasNext();)
{
Entry element = (Entry) iter.next();
params.append(element.getKey().toString());
params.append("=");
params.append(URLEncoder.encode(element.getValue().toString(),
HttpRequestProxy.requestEncoding));
params.append("&");
}
if (params.length() > 0)
{
params = params.deleteCharAt(params.length() - 1);
}
URL url = new URL(reqUrl);
url_con = (HttpURLConnection) url.openConnection();
url_con.setRequestMethod("POST");
System.setProperty("sun.net.client.defaultConnectTimeout", String
.valueOf(HttpRequestProxy.connectTimeOut));// (单位:毫秒)jdk1.4换成这个,连接超时
System.setProperty("sun.net.client.defaultReadTimeout", String
.valueOf(HttpRequestProxy.readTimeOut)); // (单位:毫秒)jdk1.4换成这个,读操作超时
// url_con.setConnectTimeout(5000);//(单位:毫秒)jdk
// 1.5换成这个,连接超时
// url_con.setReadTimeout(5000);//(单位:毫秒)jdk 1.5换成这个,读操作超时
url_con.setDoOutput(true);
byte[] b = params.toString().getBytes();
url_con.getOutputStream().write(b, 0, b.length);
url_con.getOutputStream().flush();
url_con.getOutputStream().close();
InputStream in = url_con.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(in,
recvEncoding));
String tempLine = rd.readLine();
StringBuffer tempStr = new StringBuffer();
String crlf=System.getProperty("line.separator");
while (tempLine != null)
{
tempStr.append(tempLine);
tempStr.append(crlf);
tempLine = rd.readLine();
}
responseContent = tempStr.toString();
rd.close();
in.close();
}
catch (IOException e)
{
logger.error("网络故障", e);
}
finally
{
if (url_con != null)
{
url_con.disconnect();
}
}
return responseContent;
}
/**
* @return 连接超时(毫秒)
* @see com.hengpeng.common.web.HttpRequestProxy#connectTimeOut
*/
public static int getConnectTimeOut()
{
return HttpRequestProxy.connectTimeOut;
}
/**
* @return 读取数据超时(毫秒)
* @see com.hengpeng.common.web.HttpRequestProxy#readTimeOut
*/
public static int getReadTimeOut()
{
return HttpRequestProxy.readTimeOut;
}
/**
* @return 请求编码
* @see com.hengpeng.common.web.HttpRequestProxy#requestEncoding
*/
public static String getRequestEncoding()
{
return requestEncoding;
}
/**
* @param connectTimeOut 连接超时(毫秒)
* @see com.hengpeng.common.web.HttpRequestProxy#connectTimeOut
*/
public static void setConnectTimeOut(int connectTimeOut)
{
HttpRequestProxy.connectTimeOut = connectTimeOut;
}
/**
* @param readTimeOut 读取数据超时(毫秒)
* @see com.hengpeng.common.web.HttpRequestProxy#readTimeOut
*/
public static void setReadTimeOut(int readTimeOut)
{
HttpRequestProxy.readTimeOut = readTimeOut;
}
/**
* @param requestEncoding 请求编码
* @see com.hengpeng.common.web.HttpRequestProxy#requestEncoding
*/
public static void setRequestEncoding(String requestEncoding)
{
HttpRequestProxy.requestEncoding = requestEncoding;
}
public static void main(String[] args)
{
Map map = new HashMap();
map.put("actionType", "1");
// map.put("issueId", "33");
String temp = HttpRequestProxy.doPost("http://192.168.0.99/AgentPortal/autoHandler", map, "GBK");
System.out.println("返回的消息是:"+temp);
}
}
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/320994622009616102329953
posted @
2009-07-16 10:23 C.B.K 阅读(1803) |
评论 (1) |
编辑 收藏
/*
下面的程序说明了怎样实现对象序列化和反序列化。它由实例化一个MyClass类的对象开始。该对象有三个实例变量,它们的类型分别是String,int和double。这是我们希望存储和恢复的信息。
FileOutputStream被创建,引用了一个名为“serial”的文件。为该文件流创建一个ObjectOutputStream。ObjectOutputStream 的writeObject( )方法用来序列化对象。对象的输出流被刷新和关闭。
然后,引用名为“serial”的文件创建一个FileInputStream类并为该文件创建一个ObjectInputStream类。ObjectInputStream 的readObject( )方法用来反序列化对象。然后对象输入流被关闭。
注意MyClass被定义成实现Serializable接口。如果不这样做,将会引发一个NotSerializableException异常。试图做一些把MyClass实例变量声明成transient的实验。那些数据在序列化过程中不被保存
*/
import java.io.*;
class MyClass implements Serializable{
String s;
int i;
double d;
public MyClass (String s,int i,double d){
this.s = s;
this.i = i;
this.d = d;
}
public String toString(){
return "s=" + s + "; i=" + i + "; d=" + d;
}
}
class SerializationDemo{
public static void main(String[] args){
//Object serialization.
try{
MyClass object1 = new MyClass("Evan",9,9.9e10);
System.out.println("object1 : " +object1);
FileOutputStream fos = new FileOutputStream("serial");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object1);
oos.flush();
oos.close();
}catch(Exception e){
System.out.println("Exception during serialization :" + e);
System.exit(0);
}
//Object deserialization.
try{
MyClass object2 ;
FileInputStream fis = new FileInputStream("serial");
ObjectInputStream ois = new ObjectInputStream(fis);
object2 = (MyClass)ois.readObject();
ois.close();
System.out.println("object2 : " +object2);
}catch(Exception e){
System.out.println("Exception during serialization :" + e);
System.exit(0);
}
}
}
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/320994622009616101541196
posted @
2009-07-16 10:16 C.B.K 阅读(168) |
评论 (0) |
编辑 收藏
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想
用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220096161094144
posted @
2009-07-16 10:09 C.B.K 阅读(152) |
评论 (0) |
编辑 收藏
2009年7月10日
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内): [^\x00-\xff]
应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}
匹配空行的正则表达式: \n[\s| ]*\r
匹配HTML标记的正则表达式: /<(.*)>.*<\/>|<(.*) \/>/
匹配首尾空格的正则表达式: (^\s*)|(\s*$)
应用:javascript中没有像vbscript那样的trim函数,我们就可以利用这个表达式来实现,如下:
String.prototype.trim = function() {
return this.replace(/(^\s*)|(\s*$)/g, "");
}
利用正则表达式分解和转换IP地址:
下面是利用正则表达式匹配IP地址,并将IP地址转换成对应数值的javascript程序:
function IP2V(ip) {
re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正则表达式
if(re.test(ip)) {
return RegExp.*Math.pow(255,3))+RegExp.*Math.pow(255,2))+RegExp.*255+RegExp.*1
}
else {
throw new Error("Not a valid IP address!")
}
}
不过上面的程序如果不用正则表达式,而直接用split函数来分解可能更简单,程序如下:
var ip="10.100.20.168"
ip=ip.split(".")
alert("IP值是:"+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))
匹配Email地址的正则表达式: \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
匹配网址URL的正则表达式: http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
利用正则表达式去除字串中重复的字符的算法程序:
var s="abacabefgeeii"
var s1=s.replace(/(.).*/g,"")
var re=new RegExp("["+s1+"]","g")
var s2=s.replace(re,"")
alert(s1+s2) //结果为:abcefgi
用正则表达式从URL地址中提取文件名的javascript程序,如下结果为page1
s="http://www.9499.net/page1.htm"
s=s.replace(/(.*\/)([^\.]+).*/ig,"")
alert(s)
利用正则表达式限制网页表单里的文本框输入内容:
用正则表达式限制只能输入中文:
onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')"
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"
用正则表达式限制只能输入全角字符:
onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,'')"
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))"
用正则表达式限制只能输入数字:
onkeyup="value=value.replace(/[^\d]/g,'')
"onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"
用正则表达式限制只能输入数字和英文:
onkeyup="value=value.replace(/[\W]/g,'')
"onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200961005220547
posted @
2009-07-10 12:52 C.B.K 阅读(206) |
评论 (0) |
编辑 收藏
ant手册中的ant配置classpath采用classpath标签,可是我发现这样配置总是不好用,还是直接用path可以使用
设置classpath的方法有多种
<path id="project.classpath">
1<pathelement path="${basedir}/lib/aa.jar"/>
2<pathelement location="aa.jar"/>与1的区别在于location可以去当前路径,当然可以使用绝对路径
3<filelist id="file" dir="${basedir}/lin">
<file name="a.jar"/>
<file name="d:lib/b.jar"/>
</filelist>
4<fileset dir="d:/lib">
<include name="**/*.jar"/>
</fileset>
5手册上说了dirset也好用,但是我测试了还是不要用的
</path>
下面说classpath的使用
样例如下
<javac scdir="./src" destdir="./classes">
<classpath refid="project.classpath"/>
</javac>
下面是比较四种方式的优缺点
第一种调用的需要设置绝对路径适合第三方jar包
第二种则适合jar包和build.xml文件在同一目录下的情况,但是我觉得两个文件放在一起本身就不合理,估计是用的情况不多。
前两个都是设置单个jar包
第三种是一个文件集合适合引入不同路径的jar包,但是需要输入每个jar包的名字,比较繁琐,适合于jar包属于不同位置,比较分散但是不多的情况
第四种是一个文件夹,可以采用匹配模式来引入,这个适合在同一个文件夹下,文件名字比较多的情况下
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200961051533899
posted @
2009-07-10 05:16 C.B.K 阅读(1641) |
评论 (0) |
编辑 收藏
ant的构建文件中,有很多核心类型,这些核心类型都是XXXSet的形式,主要有以下几个:PatternSet、DirSet、FileSet、PropertySet、ZipFileSet等。说下前三个的功能就应该可以举一反三了。
1.PatternSet
即模式集合。顾名思义,就是定义一个模式,他可以用来指定一个文件集合。常常可以被外部的target引用,复用性很强。有includes、
includesfile、excludes、excludesfile属性。每个属性里面还可以嵌套name、if、unless等类型。
2.DirSet 即目录集合。用来定义目录的集合。有dir、casesensitive、followsymlinks和PatternSet也有的那4个属性。上面说过PatternSet可以很好的复用。下面就是一个例子:
- <dirset dir="${build.dir}">
- <patternset id="non.test.classes">
- <include name="apps/**/classes"/>
- <exclude name="apps/**/*Test*"/>
- </patternset>
- </dirset>
<dirset dir="${build.dir}">
<patternset id="non.test.classes">
<include name="apps/**/classes"/>
<exclude name="apps/**/*Test*"/>
</patternset>
</dirset>
这是用patternset来定义DirSet的模式,这个模式还可以在外部引用。如:
- <dirset dir="{build.dir}">
- <patternset refid="non.test.classes"/>
- </dirset>
<dirset dir="{build.dir}">
<patternset refid="non.test.classes"/>
</dirset>
上面定义了一个名为non.test.classes的PatternSet,现在就可以引用他了。refid即reference ID.
3.FileSet即文件集合,他的内部属性与DirSet几乎一样,只是多了一个file和defaultexcludes。和dirset一样,经常
嵌入patternset来定义文件集合;但是也有另外一个很常用的类型,叫selector,它并不是一个真正的类型或元素,只是一种、一类类型的统
称。如contains、date、depend、depth、different、filename、present、containsregexp、
size、type等。
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220096105521217
posted @
2009-07-10 05:05 C.B.K 阅读(424) |
评论 (0) |
编辑 收藏
2009年6月29日
第一种方法:
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON <dbname>.*
-> TO <username>@<host name>
-> IDENTIFIED BY '<password>';
where <dbname> is the name of the database you are tyring to
connect to, <username> is the username of the user trying to
connect to the database, <host name> the name of the host (in
your case the XXX host) and <password> the password of the user.
第二种方法:
通过客户端软件设置用户的主机以及权限,
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200952925050579
posted @
2009-06-29 14:51 C.B.K 阅读(1555) |
评论 (0) |
编辑 收藏
2009年6月23日
一、什么是条件变量
与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。
条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。
条
件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条件
变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步。
使用条件变量之前要先进行初始化。可以在单个语句中生成和初始化一个条件变量如:
pthread_cond_t my_condition=PTHREAD_COND_INITIALIZER;(用于进程间线程的通信)。
也可以利用函数pthread_cond_init动态初始化。
二、条件变量函数
1.
名称: |
pthread_cond_init |
目标: |
条件变量初始化 |
头文件: |
#include < pthread.h> |
函数原形: |
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); |
参数: |
cptr 条件变量
attr 条件变量属性 |
返回值: |
成功返回0,出错返回错误编号。 |
pthread_cond_init函数可以用来初始化一个条件变量。他使用变量attr所指定的属性来初始化一个条件变量,如果参数attr为空,那么它将使用缺省的属性来设置所指定的条件变量。
2.
名称: |
pthread_cond_destroy |
目标: |
条件变量摧毁 |
头文件: |
#include < pthread.h> |
函数原形: |
int pthread_cond_destroy(pthread_cond_t *cond); |
参数: |
cptr 条件变量 |
返回值: |
成功返回0,出错返回错误编号。 |
pthread_cond_destroy函数可以用来摧毁所指定的条件变量,同时将会释放所给它分配的资源。调用该函数的进程也并不要求等待在参数所指定的条件变量上。
3.
名称: |
pthread_cond_wait/pthread_cond_timedwait |
目标: |
条件变量等待 |
头文件: |
#include < pthread.h> |
函数原形: |
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t mytex,const struct timespec *abstime); |
参数: |
cond 条件变量
mutex 互斥锁 |
返回值: |
成功返回0,出错返回错误编号。 |
第一个参数*cond是指向一个条件变量的指针。第二个参数*mutex则是对相关的互斥锁的指针。函数pthread_cond_timedwait函数类型与函数pthread_cond_wait,区别在于,如果达到或是超过所引用的参数*abstime,它将结束并返回错误ETIME.pthread_cond_timedwait函数的参数*abstime指向一个timespec结构。该结构如下:
typedef struct timespec{
time_t tv_sec;
long tv_nsex;
}timespec_t;
3.
名称: |
pthread_cond_signal/pthread_cond_broadcast |
目标: |
条件变量通知 |
头文件: |
#include < pthread.h> |
函数原形: |
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond); |
参数: |
cond 条件变量 |
返回值: |
成功返回0,出错返回错误编号。 |
参数*cond是对类型为pthread_cond_t 的一个条件变量的指针。当调用pthread_cond_signal时一个在相同条件变量上阻塞的线程将被解锁。如果同时有多个线程阻塞,则由调度策略确定接收通知的线程。如果调用pthread_cond_broadcast,则将通知阻塞在这个条件变量上的所有线程。一旦被唤醒,线程仍然会要求互斥锁。如果当前没有线程等待通知,则上面两种调用实际上成为一个空操作。如果参数*cond指向非法地址,则返回值EINVAL。
下面是一个简单的例子,我们可以从程序的运行来了解条件变量的作用。
#include <pthread.h> #include <stdio.h> #include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/
void *thread1(void *); void *thread2(void *);
int i=1; int main(void) { pthread_t t_a; pthread_t t_b;
pthread_create(&t_a,NULL,thread2,(void *)NULL);/*创建进程t_a*/ pthread_create(&t_b,NULL,thread1,(void *)NULL); /*创建进程t_b*/ pthread_join(t_b, NULL);/*等待进程t_b结束*/ pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); exit(0); }
void *thread1(void *junk) { for(i=1;i<=9;i++) { pthread_mutex_lock(&mutex);/*锁住互斥量*/ if(i%3==0) pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b进程*/ else printf("thead1:%d\n",i); pthread_mutex_unlock(&mutex);/*解锁互斥量*/
sleep(1); }
}
void *thread2(void *junk) { while(i<9) { pthread_mutex_lock(&mutex);
if(i%3!=0) pthread_cond_wait(&cond,&mutex);/*等待*/ printf("thread2:%d\n",i); pthread_mutex_unlock(&mutex);
sleep(1); }
} |
程序创建了2个新线程使他们同步运行,实现进程t_b打印20以内3的倍数,t_a打印其他的数,程序开始线程t_b不满足条件等待,线程t_a运行使a循环加1并打印。直到i为3的倍数时,线程t_a发送信号通知进程t_b,这时t_b满足条件,打印i值。
下面是运行结果:
#cc –lpthread –o cond cond.c
#./cond
thread1:1
thread1:2
thread2:3
thread1:4
thread1:5
thread2:6
thread1:7
thread1:8
thread2:9
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220095235658763
posted @
2009-06-23 17:07 C.B.K 阅读(287) |
评论 (0) |
编辑 收藏
工具:grub4dos0.4.2(想要的给我发信,我发给你,loveitdoit@163.com)
文件:fedora7.0映像文件,可在网上下载。
过程:
1.解压缩grub4dos0.4.2,把里面的 grldr和menu.lst,文件复制到c盘根目录下。
2.fedora7.0映像文件不必解压,必须放在fat32的分区里。把里面的isolinux目录下
的VMLINUZ、INITRD.IMG解压到c盘根目录下。
3.在c:\下找到menu.lst,用记事本打开并修改,删除其他命令,添加以下命令!
title Linux System Install
kernel (hd0,0)/vmlinuz
initrd (hd0,0)/initrd.img
4.修改c:\boot.ini文件,在最后面添加c:\grldr="Start GRUB"并保存即可。
5.重起系统,选择Start GRUB,开始安装。
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220095234437396
posted @
2009-06-23 16:05 C.B.K 阅读(137) |
评论 (0) |
编辑 收藏
花了半天时间研究了下下MYSQL的备份实现,发现其是在MY.CNF(MY.INI)配置文件中作的设置,直接设置服务器唯一性ID号加上其它的附加设
置,则可作为一台MASTER,而在
SLAVE机上,也只需要在配置文件中设置一下连接MASTER所需的参数即可,如果在MASTER里也加上连到SLAVE机的参数,则就是双向备份
了~~不过,这些连接参数中用到的账号需要注意权限的设置,否则会搞半天没反就急死你迪。。。
我在WIN上和LINUX上各装了MYSQL5,下面是它们的配置:
WIN(172.22.33.33)下的MASTER(由于我改了端口3327所以下面多加了个端口方面的特殊处理了)的配置(my.ini):(**一定要在mysqld配置段中配置,不象PHP,APACHE可以随便找个方便的地方配的,注意哈!!)
[mysqld]
#master 设置
server-id=1
log-bin=c:/masterlog
binlog-do-db=db5
#实现双机备份段,给MASTER同时加上SLAVE段,可选哈,如果不选,那就是WIN到LIN的主从备份
master-host=172.22.1.37
master-user=backup2
master-password=backup2
master-port=3306
master-connect-retry=60
replicate-do-db=db5
数据库中加一个账号:
GRANT FILE,REPLICATION SLAVE,REPLICATION CLIENT,SUPER ON *.*
TO [email=backup@]backup@'172.22.1.37'[/email] IDENTIFIED by 'backup';
这个权限表示,这个backup账号只能由从备份机172.22.1.37访问只能用来进行备份操作
LINUX(172.22.1.37)下的SLAVE机的配置(把安装目录里找到的任意一个*.cnf拷到/etc/my.cnf下进行修改):
server-id=2
#如果不需要双向备份下面两行可以不要
#否则还要加一个数据库用户账号
/*
GRANT FILE,REPLICATION SLAVE,REPLICATION CLIENT,SUPER ON *.*
TO [email=backup2@]backup2@'172.22.33.33'[/email] IDENTIFIED by 'backup2';
*/
log-bin=./masterlog
binlog-do-db=db5
#---------------------------------------
master-host=172.22.33.33
master-user=backup
master-password=backup
master-port=3327
master-connect-retry=60
replicate-do-db=db5
由于只是大概的弄了一下,特别是在数据库用户方面没有作仔细试验:),可能会有所不太准确的地方,还有就是,上面测试用到的数据库一定要是已经建立好并且
结构相同的,两台机子都重启后会进行检查,如果出现找不到或者检查到结构不同,会报错,最好就是在创建空数据库时或初始时安装两个一样的数据库后就建立好
关系,对于不同版本的MYSQL,官方说明也可以同步,但想一想,把MYSQL5 的数据备份到4中去丢失5的特性也没什么意义吧。。
文章来源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200952335921779
posted @
2009-06-23 15:59 C.B.K 阅读(213) |
评论 (0) |
编辑 收藏