84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
PHP队列执行任务的时候,如何防止进程之间抢夺资源?比如视频转码队列,每分钟会起一个进程去处理视频转码任务,每次从数据库获取10条进程1已经获取了ID为10的视频去处理,一分钟后,如何防止进程2 拿到其他进程已经处理过的?处理完成后,有异步通知,但是异步通知会有延迟,所以视频状态有可能修改不及时
PHP队列执行任务的时候,如何防止进程之间抢夺资源?-PHP中文网问答-PHP队列执行任务的时候,如何防止进程之间抢夺资源?-PHP中文网问答
围观一下哦,学习一下。
实际上有一个非常简单的办法,你可以利用数据库操作的原子性来实现,不需要那么复杂的锁机制,甚至队列。就按你的方法来,假设任务数据表 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 的进程,直接进入下一个等待流程即可。
PHP队列执行任务的时候,如何防止进程之间抢夺资源?-PHP中文网问答-PHP队列执行任务的时候,如何防止进程之间抢夺资源?-PHP中文网问答
围观一下哦,学习一下。
实际上有一个非常简单的办法,你可以利用数据库操作的原子性来实现,不需要那么复杂的锁机制,甚至队列。就按你的方法来,假设任务数据表 task 里有两个字段 id, status,我们定义status三个状态
假设你有一堆 PHP 进程都用如下 SQL 语句去取出数据库里的待处理任务
取出来以后,我们为了防止其他用户不再重复取出要把它的状态标记为 1
但是等等,这样就会产生如你所说的资源抢夺,但如果加上一个简单的技巧就可以避免,你把语句变成这样
熟悉一点数据库的人可能会说这样还是避免不了抢夺,只是避免了重复写入。
我要说的是,能避免重复写入就够了,我们的进程在执行完这条操作后,去获取 affected_rows ,即更新的条数,根据数据库的原子性,只有第一个抢占的进程才会返回 1,它可以进行后面的操作。而剩下返回 0 的进程,直接进入下一个等待流程即可。