Atomic [编辑本页]

swoole_atomic是swoole扩展提供的原子计数操作类,可以方便整数的无锁原子增减。

  • swoole_atomic使用共享内存,可以在不同的进程之间操作计数
  • swoole_atomic基于gcc提供的CPU原子指令,无需加锁
  • swoole_atomic在服务器程序中必须在swoole_server->start前创建才能在Worker进程中使用

注意:请勿在onReceive等回调函数中创建原子数,否则底层的GlobalMemory内存不足会创建失败。在swoole中可以创建的Atomic对象数量有限

swoole_atomic在1.7.19以上版本可用

使用示例

$atomic = new swoole_atomic(123);
echo $atomic->add(12)."\n";
echo $atomic->sub(11)."\n";
echo $atomic->cmpset(122, 999)."\n";
echo $atomic->cmpset(124, 999)."\n";
echo $atomic->get()."\n";

  • 咸鱼

    swoole_atomic 可以在多进程间共享吗?

  • Rango-韩天峰

    可以。

  • 咸鱼

    thx

  • 打杂的狼

    版本1.8.12,使用httpserver异步方式,ab并发1000压测10w个,同时后端记录原子数,发现非常多重复。求大神解答?

    压测机:

    > ab -c 1000 -n 100000 http://host:12345/

    被压测机:

    > cat log | sort | uniq -d | wc -l

    129

    代码: $GLOBALS['lockfile'] = '/tmp/test_httpserver.log';

    class HttpServer {

    public static $instance;
    
    private $server;
    private $atomic;
    private $lock;
    
    public function __construct() {
        $this->lock = new swoole_lock(SWOOLE_FILELOCK, $GLOBALS['lockfile']);
        $this->atomic = new swoole_atomic();
        $this->server = new swoole_http_server('0.0.0.0', 12345);
        $this->server->on('Request', array($this, 'onReceive'));
        $this->server->start();
    }
    
    public function onReceive(swoole_http_request $request, swoole_http_response $response) {
        $this->lock->lock();
        error_log($this->atomic->add()."\n", 3, $GLOBALS['lockfile']);
        $this->lock->unlock();
    }
    
    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new HttpServer();
        }
        return self::$instance;
    }
    

    }

    HttpServer::getInstance();

  • Rango-韩天峰

    add/sub的返回值确实存在数据同步问题,请使用1.9.0版本,已经修复了这个问题。

  • ddg

    文档还是说的 ·swoole_atomic在1.7.19以上版本可用·,要不更新到文档中吧