Når en proces afsluttes (enten fordi den afsluttes, eller den afsluttes ved hjælp af et signal), lukkes alle de filer og forbindelser, den holder åbne, automatisk af operativsystemet. Det er ikke lukket rent, ved at bruge MySQL-protokollen til at lukke forbindelser (forudsat at der er en). Den droppes ganske enkelt på TCP/IP-niveau, og serveren på den anden side opdager bare, at den taler til en lukket dør. Det sker ikke altid med det samme, nogle gange tager det noget tid, før serveren bemærker, at diskussionspartneren er væk. Når dette sker, betragter den forbindelsen som værende afbrudt og rydder tingene op på siden.
Gør det ikke åbn MySQL-forbindelsen i den overordnede proces, før du bruger fork()
. fork()
dublerer de datastrukturer, der bruges til at administrere den lokale side af forbindelsen, og resultaterne er uforudsigelige. Endnu mere, når barnet fuldfører (uanset hvordan), det lukker forbindelsen (eller OS dropper den), MySQL-serveren lukker også sin ende, og forældreprocessen opdager, at den ikke taler med nogen.
Luk MySQL-forbindelsen i den overordnede proces, før du bruger fork()
åbn derefter separate forbindelser i forældre- og underordnet processen efter behov.
Indpak også enhver MySQL-kommunikation med serveren i forældreprocessen mellem:
pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
og
pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
Ellers, når en underordnet proces er fuldført, underrettes den overordnede proces med SIGCHLD
signal. Et modtaget signal genoptager det fra dvale (hvis det tilfældigvis blev stoppet i en sleep()
ring, når signalet kommer). MySQL-biblioteket bruger sleep()
som en del af MySQL-protokollen til kommunikation med serveren. Hvis sådan en sleep()
vender tilbage tidligere end det burde (på grund af et modtaget signal), MySQL-biblioteket bliver forvirret, og det ender med at rapportere mærkelige fejl (som "MySQL-serveren er gået væk"), som faktisk ikke er korrekte.
Tag et kig på dette svar for en detaljeret forklaring.