您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
workerman常用组件-GlobalData变量共享组件-GlobalDataClient-cas
发布时间:2021-12-14 22:14:02编辑:雪饮阅读()
cas
(要求Workerman版本>=3.3.0)
bool \GlobalData\Client::cas(string $key, mixed $old_value, mixed $new_value)
原子替换,用$new_value替换$old_value。
仅在当前客户端最后一次取值后,该key对应的值没有被其他客户端修改的情况下, 才能够将值写入。
参数
$key
键值。(例如$global->abc,abc就是键值)
$old_value
老数据
$new_value
新数据
返回值
替换成功返回true,否则返回false。
说明:
多进程同时操作同一个共享变量时,有时候要考虑并发问题。
例如A B两个进程同时给用户列表添加一个成员。
A B进程当前用户列表都为$global->user_list = array(1,2,3)。
A进程操作$global->user_list变量,添加一个用户4。
B进程操作$global->user_list变量,增加一个用户5。
A进程设置变量$global->user_list = array(1,2,3,4)成功。
B进程设置变量$global->user_list = array(1,2,3,5)成功。
此时B进程设置的变量将A进程设置的变量覆盖,导致数据丢失。
以上由于读取和设置不是一个原子操作,导致并发问题。
要解决这种并发问题,可以使用cas原子替换接口。
cas接口在改变一个值之前,
会根据$old_value判断这个值是否被其它进程更改过,
如果有更改,则不替换,返回false。否则替换返回true。
见下面示例。
注意:
有些共享数据被并发覆盖是没问题的,例如竞拍系统某拍卖物当前最大报价,例如某商品当前库存等。
實例如:
<?php
require_once __DIR__ . '/vendor/autoload.php';
// 初始化一个全局的global data client
$global = new \GlobalData\Client('127.0.0.1:2207');
// 初始化列表
$global->user_list = array(1,2,3);
// 向user_list原子添加一个值
do
{
$old_value = $new_value = $global->user_list;
$new_value[] = 4;
}
//新值[1,2,3,4],替換老值[1,2,3]
while(!$global->cas('user_list', $old_value, $new_value));
var_export($global->user_list);
?>
運行該客戶端:
[root@localhost www.fpm.com]# /usr/local/php734/bin/php -c /usr/local/php734/lib/php/php.ini start.php start
array (
0 => 1,
1 => 2,
2 => 3,
3 => 4,
)
关键字词:workerman,GlobalData,GlobalDataClient,cas
上一篇:workerman常用组件-GlobalData变量共享组件-GlobalDataClient-add
下一篇:workerman常用组件-GlobalData变量共享组件-GlobalDataClient-increment
相关文章
- workerman常用组件-GlobalData变量共享组件-GlobalDat
- workerman常用组件-GlobalData变量共享组件-GlobalDat
- workerman常用组件-GlobalData变量共享组件-GlobalDat
- workerman常用组件-GlobalData变量共享组件-GlobalDat
- workerman常用组件-GlobalData变量共享组件-GlobalDat
- workerman常用组件-GlobalData变量共享组件-GlobalDat
- workerman常用组件-GlobalData变量共享组件
- workerman调试-跟踪系统调用
- workerman调试-网络抓包
- workerman实现http客户端及chunk服务端