Kiedy proces się kończy (albo z powodu zakończenia, albo zakończenia za pomocą sygnału), wszystkie pliki i połączenia, które utrzymuje, są automatycznie zamykane przez system operacyjny. Nie jest zamykany na czysto, używając protokołu MySQL do zamykania połączeń (zakładając, że taki istnieje). Jest po prostu upuszczany na poziomie TCP/IP, a serwer po drugiej stronie po prostu odkrywa, że rozmawia z zamkniętymi drzwiami. Nie zawsze dzieje się to od razu, czasami mija trochę czasu, zanim serwer zauważy, że partner do dyskusji zniknął. Kiedy tak się dzieje, traktuje połączenie jako zerwane i czyści wszystko po swojej stronie.
Nie otwórz połączenie MySQL w procesie nadrzędnym przed użyciem fork()
. fork()
duplikuje struktury danych używane do zarządzania lokalną stroną połączenia, a wyniki są nieprzewidywalne. Co więcej, kiedy dziecko zakończy (niezależnie od tego jak), zamyka połączenie (lub system operacyjny je zerwie), serwer MySQL również zamyka swoje zakończenie, a proces nadrzędny odkrywa, że z nikim nie rozmawia.
Zamknij połączenie MySQL w procesie nadrzędnym przed użyciem fork()
następnie w razie potrzeby otwórz oddzielne połączenia w procesie nadrzędnym i podrzędnym.
Ponadto zawiń każdą komunikację MySQL z serwerem w procesie nadrzędnym pomiędzy:
pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
i
pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
W przeciwnym razie, gdy proces potomny zakończy się, proces nadrzędny zostanie powiadomiony za pomocą SIGCHLD
sygnał. Odebrany sygnał wznawia go ze stanu uśpienia (jeśli został zatrzymany w sleep()
zadzwoń, gdy nadejdzie sygnał). Biblioteka MySQL używa sleep()
w ramach protokołu MySQL do komunikacji z serwerem. Jeśli taki sleep()
wymusza powrót wcześniej niż powinien (z powodu odebranego sygnału), biblioteka MySQL jest zdezorientowana i kończy zgłaszanie dziwnych błędów (takich jak „Serwer MySQL zniknął”), które w rzeczywistości nie są poprawne.
Spójrz na tę odpowiedź szczegółowe wyjaśnienie.