Atomic

基于 Swoole 提供的 Swoole\Atomic,直接在配置文件中设置,就可以在worker进程中使用,数据互通。

使用时无需加锁!

配置方式

在项目配置文件中加入以下节

  1. 'atomics' => [
  2. // 定义名为name1的,初始值为0
  3. 'name1',
  4. // 定义名为name2的,初始值为10
  5. 'name2' => 10,
  6. ],

使用方式

  1. use \Imi\Util\AtomicManager;
  2. // 获取 Swoole\Atomic 对象
  3. $atomic = AtomicManager::getInstance('name1');
  4. // 加1,返回结果
  5. $number = AtomicManager::::add('name1');
  6. // 加10,返回结果
  7. $number = AtomicManager::::add('name1', 10);
  8. // 减1,返回结果
  9. $number = AtomicManager::::sub('name1');
  10. // 减10,返回结果
  11. $number = AtomicManager::::sub('name1', 10);
  12. // 获取当前值
  13. $number = AtomicManager::get('name1');
  14. // 设置当前值为100
  15. AtomicManager::get('name1', 100);
  16. // -----------------------------------------------
  17. // 如果当前数值等于100返回true,并将当前数值设置为1
  18. // 如果当前数值不等于100返回false
  19. $number = AtomicManager::cmpset('name1', 100, 1);
  20. /**
  21. * 当原子计数的值为0时程序进入等待状态。另外一个进程调用wakeup可以再次唤醒程序。底层基于Linux Futex实现,使用此特性,可以仅用4字节内存实现一个等待、通知、锁的功能。
  22. * 超时返回false,错误码为EAGAIN,可使用swoole_errno函数获取
  23. * 成功返回true,表示有其他进程通过wakeup成功唤醒了当前的锁
  24. * 使用wait/wakeup特性时,原子计数的值只能为0或1,否则会导致无法正常使用
  25. * 当然原子计数的值为1时,表示不需要进入等待状态,资源当前就是可用。wait函数会立即返回true
  26. * @param string $name 原子计数对象名称
  27. * @param float $timeout 指定超时时间,默认为-1,表示永不超时,会持续等待直到有其他进程唤醒
  28. * @return bool
  29. */
  30. $result = AtomicManager::wait('name1');
  31. // 超时时间100毫秒
  32. $result = AtomicManager::wait('name1', 0.1);
  33. /**
  34. * 唤醒处于wait状态的其他进程。
  35. * 当前原子计数如果为0时,表示没有进程正在wait,wakeup会立即返回true
  36. * 当前原子计数如果为1时,表示当前有进程正在wait,wakeup会唤醒等待的进程,并返回true
  37. * 如果同时有多个进程处于wait状态,$n参数可以控制唤醒的进程数量
  38. * 被唤醒的进程返回后,会将原子计数设置为0,这时可以再次调用wakeup唤醒其他正在wait的进程
  39. * @param string $name 原子计数对象名称
  40. * @param integer $n
  41. * @return void
  42. */
  43. AtomicManager::wakeup('name1'); // 第二个参数我也不知道干嘛的,swoole文档没写