Maison  >  Questions et réponses  >  le corps du texte

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

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

phpcn_u747phpcn_u7472737 Il y a quelques jours1181

répondre à tous(2)je répondrai

  • 数据分析师

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

    Lorsque la file d'attente PHP exécute des tâches, comment empêcher les processus de récupérer des ressources ? - Questions et réponses sur le site Web PHP chinois - Lorsque la file d'attente PHP exécute des tâches, comment empêcher les processus de récupérer des ressources ? - Questions et réponses sur le site Web PHP chinois

    Jetez un œil et apprenez .

    répondre
    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 的进程,直接进入下一个等待流程即可。

    répondre
    0
  • Annulerrépondre