【问题标题】:Remove nth element from redis's list in thread safe way以线程安全的方式从 redis 的列表中删除第 n 个元素
【发布时间】:2014-06-23 14:34:21
【问题描述】:

在 cron 作业中,我希望在迭代期间以线程安全的方式从 redis 的列表中删除第 n 个元素。

有可能吗?我可以知道我该怎么做吗?

我正在寻找线程安全的方式。会有另一个写入进程,它会不时地对同一个列表执行写入操作。

while (true) {
    // Get all elements from "mylist" list.
    $list = $redis->lrange("mylist", 0, -1);

    // Iterate through "mylist" list.
    for ($n = 0; $n < count($list); ++$n) {
        if ($list[$n] == "dummy") {
            // I wish to remove nth element (with "dummy" value) from "mylist" 
            // in thread safe fashion. But how?
        }
    }
}

线程安全很重要,这样就不会发生以下情况

  1. Cron 作业找出“dummy”元素是第 5 个元素,并准备删除它。
  2. 编写器进程正在将附加元素插入到列表的头部,这会将“虚拟”元素推到第 6 位。
  3. Cron 作业从列表中删除了第 5 个元素,该元素不再是“虚拟”元素!

在 Java 中,我通常使用Copy On Write(通过CopyOnWriteArrayList)来解决这个读写器问题。但是,在 PHP 和 redis 中呢?

【问题讨论】:

    标签: php multithreading redis


    【解决方案1】:

    使用LREM 执行此操作:

    LREM mylist 0 "dummy"
            ^   ^    ^
            |   |    |- `value` to delete   
            |   |------ remove all elements equal to `value`.
            |---------- list key name   
    

    您可以使用count(上面示例中的0)从头到尾(或从尾到头)移动。

    【讨论】:

    • 为了完整起见,由于 Redis(大部分)是单线程的,LREM 是线程安全的。
    【解决方案2】:

    实现此目的的一种方法是使用线程安全的 php(通过在 Windows 上为 php 安装线程安全二进制文件或为 php 安装 pthreads 扩展)。就 redis 而言,它是单线程的,因此一次将更新一个列表。但是,可以通过以线程安全的方式执行循环来管理循环(实际上是修改 Redis 列表)。

    http://www.php.net//manual/en/book.pthreads.php

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多