search

Home  >  Q&A  >  body text

PHP队列执行任务的时候,如何防止进程之间抢夺资源?

PHP队列执行任务的时候,如何防止进程之间抢夺资源?
比如视频转码队列,每分钟会起一个进程去处理视频转码任务,每次从数据库获取10条
进程1已经获取了ID为10的视频去处理,一分钟后,如何防止进程2 拿到其他进程已经处理过的?
处理完成后,有异步通知,但是异步通知会有延迟,所以视频状态有可能修改不及时

phpcn_u747phpcn_u7472805 days ago1249

reply all(2)I'll reply

  • 数据分析师

    数据分析师2017-10-01 01:06:36

    When the PHP queue executes tasks, how to prevent processes from robbing resources? - PHP Chinese website Q&A - When the PHP queue executes tasks, how to prevent processes from robbing resources? - PHP Chinese website Q&A

    Come and watch and learn.

    reply
    0
  • 阿神

    阿神2017-03-23 14:59:59

    实际上有一个非常简单的办法,你可以利用数据库操作的原子性来实现,不需要那么复杂的锁机制,甚至队列。就按你的方法来,假设任务数据表 task 里有两个字段 id, status,我们定义status三个状态

    0: 待处理
    1: 正在处理
    2: 处理完成

    假设你有一堆 PHP 进程都用如下 SQL 语句去取出数据库里的待处理任务

    SELECT * FROM task WHERE status = 0

    取出来以后,我们为了防止其他用户不再重复取出要把它的状态标记为 1

    UPDATE task SET status = 1 WHERE id = xxx

    但是等等,这样就会产生如你所说的资源抢夺,但如果加上一个简单的技巧就可以避免,你把语句变成这样

    UPDATE task SET status = 1 WHERE id = xxx AND status = 0

    熟悉一点数据库的人可能会说这样还是避免不了抢夺,只是避免了重复写入。
    我要说的是,能避免重复写入就够了,我们的进程在执行完这条操作后,去获取 affected_rows ,即更新的条数,根据数据库的原子性,只有第一个抢占的进程才会返回 1,它可以进行后面的操作。而剩下返回 0 的进程,直接进入下一个等待流程即可。

    reply
    0
  • Cancelreply