以线程安全的方式从redis的列表中删除第n个元素

时间:2014-06-23 02:47:24

标签: php multithreading redis

在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找工作&#34;假&#34; element是第5个元素,并准备删除它。
  2. Writer进程正在将额外的元素插入到列表的头部,这会推动&#34; dummy&#34;元素进入第6位。
  3. Cron job从列表中删除了第5个元素,它不再是&#34; dummy&#34;元素了!
  4. 在Java中,我通常使用Copy On Write(通过CopyOnWriteArrayList)来解决这个读/写器问题。但是,在PHP&amp; redis的?

2 个答案:

答案 0 :(得分:2)

使用LREM执行此操作:

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

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

答案 1 :(得分:0)

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

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