Ketika suatu proses selesai (baik karena keluar atau dihentikan menggunakan sinyal) semua file dan koneksi yang tetap terbuka secara otomatis ditutup oleh sistem operasi. Itu tidak tertutup bersih, dengan menggunakan protokol MySQL untuk menutup koneksi (dengan asumsi ada satu). Ini mudah dijatuhkan di level TCP/IP dan server di sisi lain baru saja menemukan itu berbicara dengan pintu yang tertutup. Itu tidak selalu terjadi secara instan, terkadang dibutuhkan beberapa waktu hingga server mengetahui bahwa mitra diskusi hilang. Ketika ini terjadi, ia menganggap koneksi terputus dan membersihkan hal-hal di sisinya.
Jangan buka koneksi MySQL dalam proses induk sebelum menggunakan fork()
. fork()
menduplikasi struktur data yang digunakan untuk mengelola sisi lokal koneksi dan hasilnya tidak dapat diprediksi. Terlebih lagi, ketika anak selesai (tidak peduli bagaimana), ia menutup koneksi (atau OS menjatuhkannya), server MySQL juga menutup ujungnya dan proses induk menemukan bahwa ia tidak berbicara dengan siapa pun.
Tutup koneksi MySQL dalam proses induk sebelum menggunakan fork()
kemudian buka koneksi terpisah di induk dan di proses anak, sesuai kebutuhan.
Juga, bungkus komunikasi MySQL dengan server dalam proses induk antara:
pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
dan
pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
Jika tidak, ketika proses anak selesai, proses induk diberitahukan dengan SIGCHLD
sinyal. Sinyal yang diterima melanjutkannya dari tidur (jika kebetulan dihentikan di sleep()
panggilan ketika sinyal tiba). Pustaka MySQL menggunakan sleep()
sebagai bagian dari protokol MySQL untuk komunikasi dengan server. Jika sleep()
. seperti itu secara paksa kembali lebih awal dari yang seharusnya (karena sinyal yang diterima), perpustakaan MySQL menjadi bingung dan akhirnya melaporkan kesalahan aneh (seperti "server MySQL hilang") yang sebenarnya tidak benar.
Lihat jawaban ini untuk penjelasan rinci.