Apakah yang perlu saya lakukan jika kunci php flock gagal?

藏色散人
Lepaskan: 2023-03-13 18:16:01
asal
2238 orang telah melayarinya

Kunci PHP Flock gagal kerana $file_lock tidak digunakan selepas kaedah isRunning() keluar.

Apakah yang perlu saya lakukan jika kunci php flock gagal?

Persekitaran pengendalian artikel ini: sistem Windows 7, PHP versi 7.1, komputer DELL G3

Apakah yang perlu saya lakukan jika kunci php kumpulan gagal?

Penyelesaian kepada masalah kegagalan kumpulan php:

Dalam dua hari lalu, saya menulis kaedah untuk projek masa lapang saya untuk mengelakkan pelaksanaan serentak skrip PHP dijadualkan oleh crontab .

Bagaimana untuk melakukannya

Secara amnya, dengan menggunakan kaedah kumpulan kunci fail, skrip PHP yang sama mengunci fail cakera yang sama tanpa menyekat , ralat akan dilaporkan, oleh itu Skrip boleh keluar serta-merta.

Fenomena

Tetapi dalam praktiknya, didapati bahawa ia adalah mungkin untuk terus berkumpul di dalam fail pengawal apabila logik kawanan dikapsulkan ke dalam fungsi dalam fail lain , Tidak sah.

Sebab

Setelah menyahpepijat untuk masa yang lama, tiba-tiba saya teringat bahawa saya pernah menghadapi perangkap ini sebelum ini. .

Kod ralat adalah seperti berikut:

class Crontab
{
    /**
     * 确保任务没有并发执行
     */
    public static function isRunning() {
        global $argv;
        $ident = [];
        foreach ($argv as $idx => $value) {
            $ident[] = $idx . '=' . urlencode($value);
        }
        $ident = md5(implode('&', $ident));
        $lockDir = \Yii::getAlias('@app/runtime/crontab/');
        @mkdir($lockDir, 0755, true);
        $file_lock = fopen($lockDir . $ident, 'w+');
        $wouldBlock = 0;
        flock($file_lock, LOCK_EX | LOCK_NB, $wouldBlock);
        return $wouldBlock;
    }
}
Salin selepas log masuk
class Crontab
{
    /**
     * 确保任务没有并发执行
     */
    public static function isRunning() {
        global $argv;
 
        $ident = [];
        foreach ($argv as $idx => $value) {
            $ident[] = $idx . '=' . urlencode($value);
        }
        $ident = md5(implode('&', $ident));
 
        $lockDir = \Yii::getAlias('@app/runtime/crontab/');
 
        @mkdir($lockDir, 0755, true);
 
        $file_lock = fopen($lockDir . $ident, 'w+');
 
        $wouldBlock = 0;
        flock($file_lock, LOCK_EX | LOCK_NB, $wouldBlock);
 
        return $wouldBlock;
    }
}
Salin selepas log masuk

Jana nilai cincang unik berdasarkan parameter baris arahan, yang mewakili tugas PHP.

Buat fail kunci, laksanakan kunci bukan sekat kumpulan dan kembalikan wouldBlock untuk mengenal pasti sama ada kunci telah diduduki.

Saya memanggil kaedah Crontab::isRunning() pada entri skrip dan mendapati bahawa selepas memulakan skrip secara serentak, kunci sentiasa boleh diperolehi.

Sebab ralat ialah: selepas kaedah isRunning() keluar, $file_lock tidak digunakan lagi dan sampah dikumpul oleh PHP Pemegang fail $fp ditutup, menyebabkan kunci dilepaskan secara automatik.

Penyelesaian

class Crontab
{
    /**
     * 保存起来避免被php作为垃圾回收
     * @var null
     */
    static $file_lock = null;
    /**
     * 确保任务没有并发执行
     */
    public static function isRunning() {
        global $argv;
        $ident = [];
        foreach ($argv as $idx => $value) {
            $ident[] = $idx . '=' . urlencode($value);
        }
        $ident = md5(implode('&', $ident));
        $lockDir = \Yii::getAlias('@app/runtime/crontab/');
        @mkdir($lockDir, 0755, true);
        self::$file_lock = fopen($lockDir . $ident, 'w+');
        $wouldBlock = 0;
        flock(self::$file_lock, LOCK_EX | LOCK_NB, $wouldBlock);
        return $wouldBlock;
    }
}
Salin selepas log masuk
class Crontab
{
    /**
     * 保存起来避免被php作为垃圾回收
     * @var null
     */
    static $file_lock = null;
 
    /**
     * 确保任务没有并发执行
     */
    public static function isRunning() {
        global $argv;
 
        $ident = [];
        foreach ($argv as $idx => $value) {
            $ident[] = $idx . '=' . urlencode($value);
        }
        $ident = md5(implode('&', $ident));
 
        $lockDir = \Yii::getAlias('@app/runtime/crontab/');
 
        @mkdir($lockDir, 0755, true);
 
        self::$file_lock = fopen($lockDir . $ident, 'w+');
 
        $wouldBlock = 0;
        flock(self::$file_lock, LOCK_EX | LOCK_NB, $wouldBlock);
 
        return $wouldBlock;
    }
}
Salin selepas log masuk

Cuma pastikan pemegang fail tidak akan dilepaskan semasa keseluruhan kitaran hayat PHP, jadi simpan dalam statik kelas pembolehubah ahli di dalam.

Pembelajaran yang disyorkan: "Tutorial Video PHP"

Atas ialah kandungan terperinci Apakah yang perlu saya lakukan jika kunci php flock gagal?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan