月度归档:2013年08月

Linux 命令wc 小插曲

做开发的或多或少都会接触过wc 这个命令吧,手册里说这个命令的的作用是“print newline, word, and byte counts for each file”,一般情况下大家可以用wc -l $file 来统计文件中行数。

但是你如果按下面这样操作,就会发现一个有趣的事情。

php -r 'file_put_contents("/tmp/a.txt", implode(PHP_EOL, array(1, 2)));';
wc -l /tmp/a.txt #one line
awk '{print NR}' /tmp/a.txt #two lines

我理解的这个地方正常应该显示两行才对,因为换行符意思就是结束上一行开始新一行,所以在有一个换行符的情况下应该按两行来处理。这个在工作中有时可能需要注意下,有很多程序可能写入文件的时候都没有在最后添加换行符,所以如果直接用wc可能不够准确。

分享几枚多看邀请码

自从买了kindle之后一直用她来看书,也逐渐养成了购买正版书的习惯。之前的话一直在豆瓣买,后来豆瓣的kindle推送被亚马逊屏蔽了,就转战到多看来买书了。下面是我积累的几本电子书的多看邀请码(只能用一次哦~),需要的朋友注册的时候填写邀请码就行了,注册完成以后会免费获得邀请码对应的图书。

1.《了不起的盖茨比(英汉对照)》

241P5CE1B1C3

2.《国富论》

A42P7BD8F121

3.《王小波全集(卷一)》

EE2PBC1BEE78

4.《王小波全集(卷三)》

4DDP3CEB416C

用Memcache实现分布式的锁服务

一般情况下我们都用Memcache作为一个分布式的key/value缓存服务器,其实Memcache也可以实一些外门邪道的功能比如作为分布式锁来用。

原理其实非常简单就是memecach_add的时候,如果添加的key已经存在那么后面的添加就会失败。设想在高并发的场景下,如果存在被竞争的资源,我们就可以利用这个小trick来对资源加锁。知道了原理实现起来非常简单,下面是我初步实现的代码。


* gist: https://gist.github.com/tomheng/6149779
*/

class Lock{

private $mc = null;
private $key_prefix = "memcache_lock_service_key_";
private $all_lock_names = array();
private $expiration = 60; //one min
private $max_block_time = 15; //最长的阻塞时间
/**
* [__construct description]
*/
public function __construct(){
if(function_exists('memcache_init')){
$this->mc = memcache_connect('memcache_host', 11211);
}
}

/**
* [get_key description]
* @param [type] $name [description]
* @return [type] [description]
*/
private function get_key($name){
$key = $this->key_prefix.$name;
return $key;
}

/**
* 捕获锁
* @param [type] $name [description]
* @return [type] [description]
*/
public function begin($name, $block = true)
{
if(!$this->mc || !$name){
return false;
}
$max_block_time = $this->max_block_time;
$key = $this->get_key($name);
do{
$re = memcache_add($this->mc, $key, 1, false, $this->expiration);
if($re == true){
$this->all_lock_names[$name] = 1;
//$this->debug();
break;
}else{
//dolog('Lock failed '.$name);
}
//echo '#'.PHP_EOL;
//sleep(1);
}while($block && $max_block_time-- && !sleep(1));
return $re;
}

/**
* 释放锁
*/
public function release($name){
if(!$this->mc || !$name){
return false;
}
$key = $this->get_key($name);
$re = memcache_delete($this->mc, $key);
if($re == true){
unset($this->all_lock_names[$name]);
}
return $re;
}

/**
* 释放所有的锁
*/
public function __destruct(){
if(!$this->mc){
return false;
}
foreach ($this->all_lock_names as $name => $value) {
# code...
$this->release($name);
}
}

/**
* 调试
* @return [type] [description]
*/
public function debug(){
var_dump($this->all_lock_names);
foreach ($this->all_lock_names as $name => $value) {
$key = $this->get_key($name);
if($this->mc){
$value = memcache_get($this->mc, $key);
}else{
$value = "no such lock ";
}
echo "Lock name:$key, value:{$value}".PHP_EOL;
}
}
}