| TL;DR
PHPʵÏÖÊØ»¤½ø³Ì¿ÉÒÔͨ¹ý pcntl Óë posix À©Õ¹ÊµÏÖ¡£
±à³ÌÖÐÐèҪעÒâµÄµØ·½ÓУº
- ͨ¹ý¶þ´Î pcntl_fork() ÒÔ¼° posix_setsid ÈÃÖ÷½ø³ÌÍÑÀëÖÕ¶Ë
- ͨ¹ý pcntl_signal() ºöÂÔ»òÕß´¦Àí SIGHUP ÐźÅ
- ¶à½ø³Ì³ÌÐòÐèҪͨ¹ý¶þ´Î pcntl_fork() »òÕß pcntl_signal() ºöÂÔ SIGCHLD ÐźŷÀÖ¹×Ó½ø³Ì±ä³É Zombie ½ø³Ì
- ͨ¹ý umask() É趨ÎļþȨÏÞÑÚÂ룬·ÀÖ¹¼Ì³ÐÎļþȨÏÞ¶øÀ´µÄȨÏÞÓ°Ï칦ÄÜ
- ½«ÔËÐнø³ÌµÄ STDIN/STDOUT/STDERR ÖØ¶¨Ïòµ½ /dev/null »òÕ߯äËûÁ÷ÉÏ
Èç¹ûÒª×öµÄ¸üºÃ£¬»¹ÐèҪעÒ⣺
- Èç¹ûͨ¹ý root Æô¶¯£¬ÔËÐÐʱ¸ü»»µ½µÍȨÏÞÓû§Éí·Ý
- ¼°Ê± chdir() ·ÀÖ¹²Ù×÷´íÎó·¾¶
- ¶à½ø³Ì³ÌÐò¿¼ÂǶ¨Ê±ÖØÆô£¬·ÀÖ¹ÄÚ´æÐ¹Â¶
ʲôÊÇdaemon
ÎÄÕµÄÖ÷½ÇÊØ»¤½ø³Ì£¨daemon£©£¬Wikipedia Éϵ͍ÒåÊÇ£º
ÔÚÒ»¸ö¶àÈÎÎñµÄµçÄÔ²Ù×÷ϵͳÖУ¬ÊØ»¤½ø³Ì£¨Ó¢Ódaemon£¬/?di?m?n/»ò/?de?m?n/£©ÊÇÒ»ÖÖÔÚºǫִ́ÐеĵçÄÔ³ÌÐò¡£´ËÀà³ÌÐò»á±»ÒÔ½ø³ÌµÄÐÎʽ³õʼ»¯¡£ÊØ»¤½ø³Ì³ÌÐòµÄÃû³ÆÍ¨³£ÒÔ×Öĸ“d”½áβ£ºÀýÈ磬syslogd¾ÍÊÇÖ¸¹ÜÀíϵͳÈÕÖ¾µÄÊØ»¤½ø³Ì¡£
ͨ³££¬ÊØ»¤½ø³ÌûÓÐÈκδæÔڵĸ¸½ø³Ì£¨¼´PPID=1£©£¬ÇÒÔÚUNIXϵͳ½ø³Ì²ã¼¶ÖÐÖ±½ÓλÓÚinit֮ϡ£ÊØ»¤½ø³Ì³ÌÐòͨ³£Í¨¹ýÈçÏ·½·¨Ê¹×Ô¼º³ÉÎªÊØ»¤½ø³Ì£º¶ÔÒ»¸ö×Ó½ø³ÌÔËÐÐfork£¬È»ºóʹÆä¸¸½ø³ÌÁ¢¼´ÖÕÖ¹£¬Ê¹µÃÕâ¸ö×Ó½ø³ÌÄÜÔÚinitÏÂÔËÐС£ÕâÖÖ·½·¨Í¨³£±»³ÆÎª“Íѿǔ¡£
UNIX»·¾³¸ß¼¶±à³Ì£¨µÚ¶þ°æ£©£¨ÒÔÏÂʹÓüò³Æ APUE Ö¸´ú£© 13ÕÂÓÐÔÆ£º
ÊØ»¤½ø³ÌÒ²³É¾«Áé½ø³Ì£¨ daemon £©ÊÇÉú´æÖÜÆÚ½Ï³¤µÄÒ»ÖÖ½ø³Ì¡£ËüÃdz£³£ÔÚϵͳ×Ô¾ÙʱÆô¶¯£¬½öÔÚϵͳ¹Ø±Õʱ²ÅÖÕÖ¹¡£ÒòΪËûÃÇûÓпØÖÆÖÕ¶Ë£¬ËùÒÔ˵ËûÃÇÊÇÔÚºǫ́ÔËÐеġ£
ÕâÀï×¢Òâµ½£¬daemonÓÐÈçÏÂÌØÕ÷£º
- ûÓÐÖÕ¶Ë
- ºǫ́ÔËÐÐ
- ¸¸½ø³Ì pid Ϊ1
ÏëÒª²é¿´ÔËÐÐÖеÄÊØ»¤½ø³Ì¿ÉÒÔͨ¹ý ps -ax »òÕß ps -ef ²é¿´£¬ÆäÖÐ -x ±íʾ»áÁгöûÓпØÖÆÖն˵Ľø³Ì¡£
ʵÏÖ¹Ø×¢µã¶þ´Î fork Óë setsidfork ϵͳµ÷ÓÃ
fork ϵͳµ÷ÓÃÓÃÓÚ¸´ÖÆÒ»¸öÓ븸½ø³Ì¼¸ºõÍêÈ«ÏàͬµÄ½ø³Ì£¬ÐÂÉú³ÉµÄ×Ó½ø³Ì²»Í¬µÄµØ·½ÔÚÓÚÓ븸½ø³ÌÓÐ×Ų»Í¬µÄ pid ÒÔ¼°Óв»Í¬µÄÄÚ´æ¿Õ¼ä£¬¸ù¾Ý´úÂëÂ߼ʵÏÖ£¬¸¸×Ó½ø³Ì¿ÉÒÔÍê³ÉÒ»ÑùµÄ¹¤×÷£¬Ò²¿ÉÒÔ²»Í¬¡£×Ó½ø³Ì»á´Ó¸¸½ø³ÌÖм̳бÈÈçÎļþÃèÊö·ûÒ»ÀàµÄ×ÊÔ´¡£
PHP ÖÐµÄ pcntl À©Õ¹ÖÐʵÏÖÁË pcntl_fork() º¯Êý£¬ÓÃÓÚÔÚ PHP ÖÐ fork еĽø³Ì¡£
setsid ϵͳµ÷ÓÃ
setsid ϵͳµ÷ÓÃÔòÓÃÓÚ´´½¨Ò»¸öеĻỰ²¢É趨½ø³Ì×é id¡£
ÕâÀïÓм¸¸ö¸ÅÄ»á»°£¬½ø³Ì×é¡£
ÔÚ Linux ÖУ¬Óû§µÇ¼²úÉúÒ»¸ö»á»°£¨Session£©£¬Ò»¸ö»á»°Öаüº¬Ò»¸ö»òÕß¶à¸ö½ø³Ì×飬һ¸ö½ø³Ì×éÓÖ°üº¬¶à¸ö½ø³Ì¡£Ã¿¸ö½ø³Ì×éÓÐÒ»¸ö×鳤£¨Session Leader£©£¬ËüµÄ pid ¾ÍÊǽø³Ì×éµÄ×é id¡£½ø³Ì×鳤һµ©´ò¿ªÒ»¸öÖÕ¶Ë£¬ÕâÒ»¸öÖն˾ͱ»³ÆÎª¿ØÖÆÖÕ¶Ë¡£Ò»µ©¿ØÖÆÖÕ¶Ë·¢ÉúÒì³££¨¶Ï¿ª¡¢Ó²¼þ´íÎóµÈ£©£¬»á·¢³öÐźŵ½½ø³Ì×é×鳤¡£
ºǫ́ÔËÐгÌÐò£¨Èç shell ÖÐÒÔ&½áβִÐÐÖ¸ÁÔÚÖն˹رÕÖ®ºóÒ²»á±»É±ËÀ£¬¾ÍÊÇûÓд¦ÀíºÃ¿ØÖÆÖն˶ϿªÊ±·¢³öµÄSIGHUPÐźţ¬¶øSIGHUPÐźŶÔÓÚ½ø³ÌµÄĬÈÏÐÐΪÔòÊÇÍ˳ö½ø³Ì¡£
µ÷Óà setsid ϵͳµ÷ÓÃÖ®ºó£¬»áÈõ±Ç°µÄ½ø³Ìн¨Ò»¸ö½ø³Ì×飬Èç¹ûÔÚµ±Ç°½ø³ÌÖв»´ò¿ªÖն˵ϰ£¬ÄÇôÕâÒ»¸ö½ø³Ì×é¾Í²»»á´æÔÚ¿ØÖÆÖÕ¶Ë£¬Ò²¾Í²»»á³öÏÖÒòΪ¹Ø±ÕÖն˶øÉ±ËÀ½ø³ÌµÄÎÊÌâ¡£
PHP ÖÐµÄ posix À©Õ¹ÖÐʵÏÖÁË posix_setsid() º¯Êý£¬ÓÃÓÚÔÚ PHP ÖÐÉ趨еĽø³Ì×é¡£
¹Â¶ù½ø³Ì
¸¸½ø³Ì±È×Ó½ø³ÌÏÈÍ˳ö£¬×Ó½ø³Ì¾Í»á±ä³É¹Â¶ù½ø³Ì¡£
init ½ø³Ì»áÊÕÑø¹Â¶ù½ø³Ì£¬¼´¹Â¶ù½ø³ÌµÄ ppid ±äΪ 1¡£
¶þ´Î fork µÄ×÷ÓÃ
Ê×ÏÈ£¬setsid ϵͳµ÷Óò»ÄÜÓɽø³Ì×é×鳤µ÷Ó㬻᷵»Ø-1¡£
¶þ´Î fork ²Ù×÷µÄÑùÀý´úÂëÈçÏ£º
$pid1 = pcntl_fork();if ($pid1 > 0) { exit(0);} else if ($pid1 < 0) { exit("Failed to fork 1\n");}if (-1 == posix_setsid()) { exit("Failed to setsid\n");}$pid2 = pcntl_fork();if ($pid2 > 0) { exit(0);} else if ($pid2 < 0) { exit("Failed to fork 2\n");}
¼Ù¶¨ÎÒÃÇÔÚÖÕ¶ËÖÐÖ´ÐÐÓ¦ÓóÌÐò£¬½ø³ÌΪ a£¬µÚÒ»´Î fork »áÉú³É×Ó½ø³Ì b£¬Èç¹û fork ³É¹¦£¬¸¸½ø³Ì a Í˳ö¡£b ×÷Ϊ¹Â¶ù½ø³Ì£¬±» init ½ø³ÌÍйܡ£
´Ëʱ£¬½ø³Ì b ´¦ÓÚ½ø³Ì×é a ÖУ¬½ø³Ì b µ÷Óà posix_setsid ÒªÇóÉú³ÉеĽø³Ì×飬µ÷Óóɹ¦ºóµ±Ç°½ø³Ì×é±äΪ b¡£
´Ëʱ½ø³Ì b ÊÂʵÉÏÒѾÍÑÀëÈκεĿØÖÆÖÕ¶Ë£¬Àý³Ì£º
<?phpcli_set_process_title('process_a');$pidA = pcntl_fork();if ($pidA > 0) { exit(0);} else if ($pidA < 0) { exit(1);}cli_set_process_title('process_b');if (-1 === posix_setsid()) { exit(2);}while(true) { sleep(1);}
Ö´ÐгÌÐòÖ®ºó£º
? ~ php56 2fork1.php? ~ ps ax | grep -v grep | grep -E 'process_|PID' PID TTY STAT TIME COMMAND28203 ? Ss 0:00 process_b
´Ó ps µÄ½á¹ûÀ´¿´£¬process_b µÄ TTY ÒѾ±ä³ÉÁË £¿£¬¼´Ã»ÓжÔÓ¦µÄ¿ØÖÆÖÕ¶Ë¡£
´úÂë×ßµ½ÕâÀï£¬ËÆºõÒѾÍê³ÉÁ˹¦ÄÜ£¬¹Ø±ÕÖÕ¶ËÖ®ºó process_b ҲûÓб»É±ËÀ£¬µ«ÊÇΪʲô»¹Òª½øÐеڶþ´Î fork ²Ù×÷ÄØ£¿
StackOverflow ÉϵÄÒ»¸ö»Ø´ðдµÄºÜºÃ£º
The second fork(2) is there to ensure that the new process is not a session leader, so it won’t be able to (accidentally) allocate a controlling terminal, since daemons are not supposed to ever have a controlling terminal.
ÕâÊÇΪÁË·Àֹʵ¼ÊµÄ¹¤×÷µÄ½ø³ÌÖ÷¶¯¹ØÁª»òÕßÒâÍâ¹ØÁª¿ØÖÆÖÕ¶Ë£¬ÔÙ´Î fork Ö®ºóÉú³ÉµÄнø³ÌÓÉÓÚ²»Êǽø³Ì×é×鳤£¬ÊDz»ÄÜÉêÇë¹ØÁª¿ØÖÆÖն˵ġ£
×ÛÉÏ£¬¶þ´Î fork Óë setsid µÄ×÷ÓÃÊÇÉú³ÉеĽø³Ì×飬·ÀÖ¹¹¤×÷½ø³Ì¹ØÁª¿ØÖÆÖÕ¶Ë¡£
SIGHUP ÐźŴ¦Àí
Ò»¸ö½ø³ÌÊÕµ½ SIGHUP ÐźŵÄĬÈ϶¯×÷ÊǽáÊø½ø³Ì¡£
¶ø SIGHUP »áÔÚÈçÏÂÇé¿öÏ·¢³ö£º
- ¿ØÖÆÖն˶Ͽª£¬SIGHUP ·¢Ë͵½½ø³Ì×é×鳤
- ½ø³Ì×é×鳤Í˳ö£¬SIGHUP »á·¢Ë͵½½ø³Ì×éÖеÄǰ̨½ø³Ì
- SIGHUP ³£±»ÓÃÓÚ֪ͨ½ø³ÌÖØÔØÅäÖÃÎļþ£¨APUE ÖÐÌá¼°£¬daemon ÓÉÓÚûÓпØÖÆÖÕ¶Ë£¬±»ÈÏΪ²»¿ÉÄÜ»áÊÕµ½ÕâÒ»¸öÐźţ¬ËùÒÔÑ¡Ôñ¸´Óã©
ÓÉÓÚʵ¼ÊµÄ¹¤×÷½ø³Ì²»ÔÚǰ̨½ø³Ì×éÖУ¬¶øÇÒ½ø³Ì×éµÄ×鳤ÒѾÍ˳ö²¢ÇÒûÓпØÖÆÖÕ¶Ë£¬²»´¦ÀíÕý³£Çé¿öϵ±È»Ò²Ã»ÓÐÎÊÌ⣬Ȼ¶øÎªÁË·ÀֹżȻµÄÊÕµ½ SIGHUP µ¼Ö½ø³ÌÍ˳ö£¬Ò²ÎªÁË×ñÑÊØ»¤½ø³Ì³ÌÐòÉè¼ÆµÄ¹ßÀý£¬»¹ÊÇÓ¦µ±´¦ÀíÕâÒ»Ðźš£
Zombie ½ø³Ì´¦ÀíºÎΪ Zombie ½ø³Ì
¼òµ¥À´Ëµ£¬×Ó½ø³ÌÏÈÓÚ¸¸½ø³ÌÍ˳ö£¬¸¸½ø³ÌûÓе÷Óà wait ϵͳµ÷Óô¦Àí£¬½ø³Ì±äΪ Zombie ½ø³Ì¡£
×Ó½ø³ÌÏÈÓÚ¸¸½ø³ÌÍ˳öʱ£¬»áÏò¸¸½ø³Ì·¢ËÍ SIGCHLD Ðźţ¬Èç¹û¸¸½ø³ÌûÓд¦Àí£¬×Ó½ø³ÌÒ²»á±äΪ Zombie ½ø³Ì¡£
Zombie ½ø³Ì»áÕ¼ÓÃ¿É fork µÄ½ø³ÌÊý£¬Zombie ½ø³Ì¹ý¶à»áµ¼ÖÂÎÞ·¨ fork еĽø³Ì¡£
´ËÍ⣬Linux ϵͳÖÐ ppid Ϊ init ½ø³ÌµÄ½ø³Ì£¬±äΪ Zombie ºó»áÓÉ init ½ø³Ì»ØÊÕ¹ÜÀí¡£
Zombie ½ø³ÌµÄ´¦Àí
´Ó Zombie ½ø³ÌµÄÌØµã£¬¶ÔÓÚ¶à½ø³ÌµÄdaemon£¬¿ÉÒÔͨ¹ýÁ½¸ö;¾¶½â¾öÕâÒ»ÎÊÌ⣺
- ¸¸½ø³Ì´¦Àí SIGCHLD ÐźÅ
- ÈÃ×Ó½ø³Ì±» init ½Ó¹Ü
¸¸½ø³Ì´¦ÀíÐźÅÎÞÐè¶à˵£¬×¢²áÐźŴ¦Àí»Øµ÷º¯Êý£¬µ÷ÓûØÊÕ·½·¨¼´¿É¡£
¶ÔÓÚÈÃ×Ó½ø³Ì±» init ½Ó¹Ü£¬Ôò¿ÉÒÔͨ¹ý2´Î fork µÄ·½·¨£¬ÈõÚÒ»´Î fork ³öµÄ×Ó½ø³Ì a ÔÙ fork ³öʵ¼ÊµÄ¹¤×÷½ø³Ì b£¬Èà a ÏÈÐÐÍ˳ö£¬Ê¹µÃ b ³ÉΪ¹Â¶ù½ø³Ì£¬ÕâÑù¾ÍÄܱ» init ½ø³ÌÍйÜÁË¡£
umask
umask »á´Ó¸¸½ø³ÌÖм̳У¬Ó°Ïì´´½¨ÎļþµÄȨÏÞ¡£
PHP ÊÖ²áÉÏÌáµ½£º
umask() ½« PHP µÄ umask É趨Ϊ mask & 0777 ²¢·µ»ØÔÀ´µÄ umask¡£µ± PHP ±»×÷Ϊ·þÎñÆ÷Ä£¿éʹÓÃʱ£¬ÔÚÿ¸öÇëÇó½áÊøºó umask »á±»»Ö¸´¡£
Èç¹û¸¸½ø³ÌµÄ umask ûÓÐÉ趨ºÃ£¬ÄÇôÔÚÖ´ÐÐһЩÎļþ²Ù×÷ʱ£¬»á³öÏÖÒâÏë²»µ½µÄЧ¹û£º
? ~ cat test_umask.php<?php chdir('/tmp'); umask(0066); mkdir('test_umask', 0777);? ~ php test_umask.php? ~ ll /tmp | grep umaskdrwx--x--x 2 root root 4.0K 8ÔÂ 22 17:35 test_umask
ËùÒÔ£¬ÎªÁ˱£Ö¤Ã¿Ò»´Î¶¼Äܰ´ÕÕÔ¤ÆÚµÄȨÏÞ²Ù×÷Îļþ£¬ÐèÒªÖÃ0 umask Öµ¡£
ÖØ¶¨Ïò0/1/2
ÕâÀïµÄ0/1/2·Ö±ðÖ¸µÄÊÇ STDIN/STDOUT/STDERR£¬¼´±ê×¼ÊäÈë/Êä³ö/´íÎóÈý¸öÁ÷¡£
ÑùÀý
Ê×ÏÈÀ´¿´Ò»¸öÑùÀý£º
<?php// not_redirect_std_stream_daemon.php$pid1 = pcntl_fork();if ($pid1 > 0) { exit(0);} else if ($pid1 < 0) { exit("Failed to fork 1\n");}if (-1 == posix_setsid()) { exit("Failed to setsid\n");}$pid2 = pcntl_fork();if ($pid2 > 0) { exit(0);} else if ($pid2 < 0) { exit("Failed to fork 2\n");}umask(0);declare(ticks = 1);pcntl_signal(SIGHUP, SIG_IGN);echo getmypid() . "\n";while(true) { echo time() . "\n"; sleep(10);}
ÉÏÊö´úÂ뼸ºõÍê³ÉÁËÎÄÕÂ×ʼ²¿·ÖÌá¼°µÄ¸÷¸ö·½Ã棬Ψһ²»Í¬µÄÊÇûÓжԱê×¼Á÷×ö´¦Àí¡£Í¨¹ýphp not_redirect_std_stream_daemon.php Ö¸ÁîÒ²ÄÜÈóÌÐòÔÚºǫ́½øÐС£
ÔÚ sleep µÄ¼ä϶£¬¹Ø±ÕÖÕ¶Ë£¬»á·¢ÏÖ½ø³ÌÍ˳ö¡£
ͨ¹ý strace ¹Û²ìϵͳµ÷ÓõÄÇé¿ö£º
? ~ strace -p 6723Process 6723 attached - interrupt to quitrestart_syscall(<... resuming interrupted call ...>) = 0write(1, "1503417004\n", 11) = 11rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0nanosleep({10, 0}, 0x7fff71a30ec0) = 0write(1, "1503417014\n", 11) = -1 EIO (Input/output error)close(2) = 0close(1) = 0munmap(0x7f35abf59000, 4096) = 0close(0) = 0
·¢ÏÖ·¢ÉúÁË EIO ´íÎ󣬵¼Ö½ø³ÌÍ˳ö¡£
ÔÒòºÜ¼òµ¥£¬¼´ÎÒÃDZàдµÄ daemon ³ÌÐòʹÓÃÁ˵±Ê±Æô¶¯Ê±ÖÕ¶ËÌṩµÄ±ê×¼Á÷£¬µ±Öն˹رÕʱ£¬±ê×¼Á÷±äµÃ²»¿É¶Á²»¿Éд£¬Ò»µ©³¢ÊÔ¶Áд£¬»áµ¼Ö½ø³ÌÍ˳ö¡£
ÔÚÐź£ÁúµÄ²©ÎÄ¡¶Ò»¸öechoÒýÆðµÄ½ø³Ì±ÀÀ£¡·ÖÐÒ²Ìáµ½¹ýÀàËÆµÄÎÊÌâ¡£
½â¾ö·½°¸APUE ÑùÀý
APUE 13.3ÖÐÌáµ½¹ýÒ»Ìõ±à³Ì¹æÔò£¨µÚ6Ìõ£©£º
Ä³Ð©ÊØ»¤½ø³Ì´ò¿ª /dev/null ʱÆÚ¾ßÓÐÎļþÃèÊö·û0¡¢1ºÍ2£¬ÕâÑù£¬ÈκÎÒ»¸öÊÓͼ¶Á±ê×¼ÊäÈ롢д±ê×¼Êä³ö»òÕß±ê×¼´íÎóµÄ¿âÀý³Ì¶¼²»»á²úÉúÈκÎЧ¹û¡£ÒòÎªÊØ»¤½ø³Ì²¢²»ÓëÖÕ¶ËÉ豸Ïà¹ØÁª£¬ËùÒÔ²»ÄÜÔÚÖÕ¶ËÉ豸ÉÏÏÔʾÆ÷Êä³ö£¬Ò²ÎÞ´Ó´Ó½»»¥Ê½Óû§ÄÇÀï½ÓÊÜÊäÈë¡£¼°Ê±ÊØ»¤½ø³ÌÊÇ´Ó½»»¥Ê½»á»°Æô¶¯µÄ£¬µ«ÒòÎªÊØ»¤½ø³ÌÊÇÔÚºǫ́ÔËÐеģ¬ËùÒԵǼ»á»°µÄÖÕÖ¹²¢²»Ó°ÏìÊØ»¤½ø³Ì¡£Èç¹ûÆäËûÓû§ÔÚͬһÖÕ¶ËÉ豸ÉϵǼ£¬ÎÒÃÇÒ²²»»áÔÚ¸ÃÖÕ¶ËÉϼûµ½ÊØ»¤½ø³ÌµÄÊä³ö£¬Óû§Ò²²»¿ÉÆÚÍûËûÃÇÔÚÖÕ¶ËÉϵÄÊäÈë»áÓÉÊØ»¤½ø³Ì¶ÁÈ¡¡£
¼òµ¥À´Ëµ£º
- daemon ²»Ó¦Ê¹Óñê×¼Á÷
- 0/1/2 ÒªÉ趨³É /dev/null
Àý³ÌÖÐʹÓãº
for (i = 0; i < rl.rlim_max; i++) close(i);fd0 = open("/dev/null", O_RDWR);fd1 = dup(0);fd2 = dup(0);
ʵÏÖÁËÕâÒ»¸ö¹¦ÄÜ¡£dup() £¨²Î¿¼Êֲᣩϵͳµ÷ÓÃ»á¸´ÖÆÊäÈë²ÎÊýÖеÄÎļþÃèÊö·û£¬²¢¸´ÖƵ½×îСµÄδ·ÖÅäÎļþÃèÊö·ûÉÏ¡£ËùÒÔÉÏÊöÀý³Ì¿ÉÒÔÀí½âΪ£º
¹Ø±ÕËùÓпÉÒÔ´ò¿ªµÄÎļþÃèÊö·û£¬°üÀ¨±ê×¼ÊäÈëÊä³ö´íÎó£»´ò¿ª/dev/null²¢¸³Öµ¸ø±äÁ¿fd0£¬ÒòΪ±ê×¼ÊäÈëÒѾ¹Ø±ÕÁË£¬ËùÒÔ/dev/null»á°ó¶¨µ½0£¬¼´±ê×¼ÊäÈ룻ÒòΪ×îСδ·ÖÅäÎļþÃèÊö·ûΪ1£¬¸´ÖÆÎļþÃèÊö·û0µ½ÎļþÃèÊö·û1£¬¼´±ê×¼Êä³öÒ²°ó¶¨µ½/dev/null£»ÒòΪ×îСδ·ÖÅäÎļþÃèÊö·ûΪ2£¬¸´ÖÆÎļþÃèÊö·û0µ½ÎļþÃèÊö·û2£¬¼´±ê×¼´íÎóÒ²°ó¶¨µ½/dev/null£»¿ªÔ´ÏîĿʵÏÖ£ºWorkerman
Workerman ÖÐµÄ Worker.php ÖÐµÄ resetStd() ·½·¨ÊµÏÖÁËÀàËÆµÄ²Ù×÷¡£
/*** Redirect standard input and output.** @throws Exception*/public static function resetStd(){ if (!self::$daemonize) { return; } global $STDOUT, $STDERR; $handle = fopen(self::$stdoutFile, "a"); if ($handle) { unset($handle); @fclose(STDOUT); @fclose(STDERR); $STDOUT = fopen(self::$stdoutFile, "a"); $STDERR = fopen(self::$stdoutFile, "a"); } else { throw new Exception('can not open stdoutFile ' . self::$stdoutFile); }}
Workerman ÖÐÈç´ËʵÏÖ£¬½áºÏ²©ÎÄ£¬¿ÉÄÜÓë PHP µÄ GC »úÖÆÓйأ¬¶ÔÓÚ fd 0 1 2À´Ëµ£¬PHP »áά³Ö¶ÔÕâÈý¸ö×ÊÔ´µÄÒýÓüÆÊý£¬ÔÚÖ±½Ó fclose Ö®ºó£¬»áʹµÃÕ⼸¸ö fd ¶ÔÓ¦µÄ×ÊÔ´ÀàÐ͵ıäÁ¿ÒýÓüÆÊýΪ0£¬µ¼Ö´¥·¢»ØÊÕ¡£ËùÐèÒª×öµÄ¾ÍÊǽ«ÕâЩ±äÁ¿±äΪȫ¾Ö±äÁ¿£¬±£Ö¤ÒýÓõĴæÔÚ¡£
×÷ÕߣºÀÖÓã²¥¿ÍPHPÅàѵѧԺ
Ê×·¢£ºhttp://php.ithcast.com/
|