Cron Jobs发起的命令行立即运行多个PHP脚本

问题描述 投票:0回答:2
此后已删除此帖子。

php linux multithreading cron
2个回答
1
投票
将再次调用脚本时,将中断第一个执行 (每分钟都被称为),即使第一个执行 完成了吗?

没有,除非您在被调用的脚本中处理此情况,否则它不会中断。解决该问题的一种常见方法是使用
locks

或实现mutualublufusion.有许多实施PHP锁定的方法,并且没有“最佳”方法。您是否可以选择最适合您平台上可用的后端的一种,或为不同平台甚至不同的用例实施多个储物柜。当心,您应该确保您始终在同一主机上使用相同的储物柜作为特定作业!

可以用作锁定后端的流行工具中的一些:

Flock

    Redis
  • mysql
  • GET_LOCK
  • IS_USED_LOCK
  • RELEASE_LOCK
    
    
    
    示例
    以下代码实现了基于
    Phpredis
  • 扩展的抽象储物柜类和示例实现。
namespace Acme; class Factory { /// @var \Redis private static $redis; public static function redis() { if (!static::$redis) { try { static::$redis = new \Redis(); // In practice you should fetch the host from a configuration object. static::$redis->pconnect('/tmp/redis.sock'); } catch (\Exception $e) { trigger_error($e->getMessage(), E_USER_WARNING); return false; } } return static::$redis; } /** * @param mixed $id ID of a job or group of jobs * @return AbstractLocker */ public static function locker($id) { return new RedisLocker($id); } } abstract class AbstractLocker { abstract public function __construct($id); abstract public function lock(); abstract public function unlock(); abstract public function isLocked(); } class RedisLocker extends AbstractLocker { /// Key prefix const PREFIX = 'lock/'; /// @var \Redis private static $redis; /// @var string DB item key private $key; /// @var int Expiration time in seconds private $expire = 86400; /** * @param mixed $id ID of a job or group of jobs */ public function __construct($id) { if (!static::$redis) { static::$redis = Factory::redis(); } $this->key = static::PREFIX . '/' . $id; } public function lock() { $this->_fixDeadlocks(); $r = static::$redis; // Set the key to the current process ID // within a transaction (see http://redis.io/topics/transactions). $r->multi(); $result = $r->setnx($this->key, getmypid()); $r->setTimeout($this->key, $this->expire); $r->exec(); return (bool) $result; } public function unlock() { $r = static::$redis; // Delete the key from DB within a transaction. $r->multi(); $result = $r->delete($this->key); $r->exec(); return (bool) $result; } public function isLocked() { $this->_fixDeadlocks(); return (bool) static::$redis->exists($this->key); } private function _fixDeadlocks() { $r = static::$redis; if (!$r->exists($this->key) || (!$pid = $r->get($this->key))) { return; } $running = (bool) posix_kill($pid, 0); if ($pid && $running) { // Another process is running normally return; } if (!$running) { // Process is not running, so the keys must not exist if ($r->exists($this->key) && $pid == $r->get($this->key)) { // Deadlock found $this->unlock(); } } } } ////////////////////////////////////////////////////////////////// // Usage $id = 'Bubbles'; $locker = Factory::locker($id); if ($locker->isLocked()) { trigger_error("$id job is locked"); exit(1); } $locker->lock(); for ($i = 0; $i < 10; ++$i) { echo '. o O '; usleep(1e6); } echo PHP_EOL; $locker->unlock();

测试

terminala

$ php script.php . o O . o O . o O . o O . o O . o

末端B

$ php script.php Notice: Bubbles job is locked in /home/ruslan/tmp/script.php on line 121

没有,将产生一个新的过程。快速测试显示了这一点:

shell> cat /root/run_sleep.sh #!/bin/bash sleep 10000 shell> crontab -l * * * * * sh /root/run_sleep.sh

您可以检查每分钟创建不同的过程:
ps

0
投票

没有,对脚本的每个调用都独立于其他呼叫,但是您应该考虑到脚本每次数据库同时运行时,数据库将被超载...建议至少每两分钟运行脚本(*/2)
    

像Pepo一样说话。这打开了一个新的过程。某些情况可能是一个问题。为了解决这个问题,您可以像Laravel一样使用Jobqueue。或者,您可以创建一个更好的任务列表,以与您的Aplication过程相似,类似于Jobqueue,有些喜欢具有列表的表或文件来处理操作/功能,以及对项目待定/处理/处理的状态。 有了多个进程的问题,请在进程之前检查您的数据。

	

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.