När en process slutförs (antingen för att den avslutas eller för att den avslutas med en signal) stängs alla filer och anslutningar som den håller öppna automatiskt av operativsystemet. Det stängs inte rent, genom att använda MySQL-protokollet för att stänga anslutningar (förutsatt att det finns en). Den släpps enkelt på TCP/IP-nivå och servern på andra sidan upptäcker precis att den pratar med en stängd dörr. Det händer inte alltid direkt, ibland tar det lite tid innan servern märker att diskussionspartnern är borta. När detta händer, anser den att anslutningen har tappats och rensar upp sakerna på sidan.
Gör inte öppna MySQL-anslutningen i den överordnade processen innan du använder fork()
. fork()
duplicerar datastrukturerna som används för att hantera den lokala sidan av anslutningen och resultaten är oförutsägbara. Ännu mer, när barnet slutför (oavsett hur), stänger det anslutningen (eller operativsystemet släpper den), MySQL-servern stänger också sin ände och förälderprocessen upptäcker att den inte pratar med någon.
Stäng MySQL-anslutningen i den överordnade processen innan du använder fork()
öppna sedan separata kopplingar i föräldern och i barnprocessen, efter behov.
Lägg även in eventuell MySQL-kommunikation med servern i den överordnade processen mellan:
pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
och
pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
Annars, när en underordnad process slutförs, meddelas den överordnade processen med SIGCHLD
signal. En mottagen signal återupptar den från viloläge (om den råkade stoppas i en sleep()
ring när signalen kommer). MySQL-biblioteket använder sleep()
som en del av MySQL-protokollet för kommunikation med servern. Om en sådan sleep()
tvångsåterkommer tidigare än det borde (på grund av en mottagen signal), MySQL-biblioteket blir förvirrat och det slutar med att det rapporterar konstiga fel (som "MySQL-servern är borta") som faktiskt inte är korrekta.
Ta en titt på det här svaret för en detaljerad förklaring.