您的位置:首页 > 编程语言 > PHP开发

PHP信号控制,ID生成器应用

2016-07-21 17:39 441 查看
1.举例

以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。

2.使用:

$key=ftok(__FILE__,'t');

/**
获取一个信号量资源
int $key [, int $max_acquire = 1 [, int $perm = 0666 [, int $auto_release = 1 ]]]
$max_acquire:最多可以多少个进程同时获取信号
$perm:权限 默认 0666
$auto_release:是否自动释放信号量
*/
$sem_id=sem_get($key);

#获取信号,其他进程阻塞
sem_acquire($sem_id);

//do something 这里是一个原子性操作

//释放信号量
sem_release($sem_id);

//把次信号从系统中移除
sem_remove($sem_id);


3.ID生成器(多用于拆表,保证ID不重复)

/**
* 获取表的ID.
*
* @param string $table 表名.
*
* @return integer
*/
function getId($table)
{
$key=ftok(__FILE__, $table);

// 获取一个信号量资源.
$sem_id=sem_get($key);

// 创建OR获取共享内存.
$shm_attach = shm_attach($key, 1024);

#获取信号,其他进程阻塞.(必须等待信号释放才能获取...)
sem_acquire($sem_id);

// 获取共享内存数据.
$shm_key = 9; // 共享内存变量.
$result = shm_get_var($shm_attach, $shm_key);
$result = unserialize($result);

// 判断是否有ID或者ID满足条件.
if (is_array($result) && ($result['current'] < $result['max'])) {
$result['current'] += 1;
$id = $result['current'];
} else {
// 更新数据库.
$id = getIdFromDb($table);
$result['current'] = $id;
$result['max'] = $id + rand(999, 1999);
}
shm_put_var($shm_attach, $shm_key, serialize($result));
// 关闭共享内存.
shm_detach($shm_attach);
//释放信号量.
sem_release($sem_id);
return $id;
}

/**
* 从数据库获取ID.
*
* @param string $table 表名.
*
* @return integer
*/
function getIdFromDb($table)
{
// 数据库连接(自己实现).
$db = 0;
$id = $db->fetchColumn("select id from idNum where name='{$table}'");
// 初始化.
if (empty($id)) {
$id = 1;
$db->exec("insert into idNum (name, id) values ('{$table}', {$id})");
}
$res = $db->exec("update idNum set id=id+2000 where id = {$id} and name = '{$table}'");
if (!$res) {
$id = getIdFromDb($table);
}
$db->close();
return $id;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: