system(dirname(__FILE__)."/1.sh > /dev/null 2>&1 &");
#/bin/sh
sleep 10
При выполнении fork открытые файлы и сокеты наследуются дочерним процессом. exec, который подменяет копию процесса на другой исполняемый файл не закрывает открытые файлы и сокеты по этому и получается что дочерний процесс унаследовал открытый сокет предка.ежу понятно, что сам процесс к этому отношения не имеет
но почему так и что это значит - я не знаю
и чтоб не рождать зомбиков я и использую сишную форкалкури выполнении fork открытые файлы и сокеты наследуются дочерним процессом. exec, который подменяет копию процесса на другой исполняемый файл не закрывает открытые файлы и сокеты по этому и получается что дочерний процесс унаследовал открытый сокет предка.
Я вот пока не могу понять, где в примере grigori могут возникать зомби. Может он просто словил момент, когда процесс уже умер, но его предок еще не прочитал его статус? (у меня такое иногда top показывает из-за того, что он не реалтаймовый, а обновляет информацию через некоторые промежутки времени).и чтоб не рождать зомбиков я и использую сишную форкалку
<defunct> - это процесс зомби, который уже умер. Его исполняемый код уже выгружен из памяти, все дискрипторы закрыты, а ресурсы освобождены. Тоесть никаким вводом выводом он заниматься не может, потому что процесса уже нет. В таблице процессов ядра осталась только информация о его смерти и его код завершения.Все что он мог, он исполнил, а вывод ему умереть не дает. Если делаем > /dev/null, то sh потоков никаких не получает от дочки и соответственно дохнет естественной смертью.
А в случае "prog > /dev/null 2>&1 &" Программа действительно запускается в фоне и не умирает по вине PHP через некоторое время?sh был defunct все 10 секунд
верно и блокировка PHP возникает из-за открытых PHP файловых дескрипторов для связи с стандартным вводом/выводом дочернего процесса. (В случае /dev/null 2>&1 потоки дочернего процесса связываются с /dev/null, а дескрипторы, которые создал PHP будут закрыты sh в момент смерти)Хотя есть подозрение, что в случае system...
grigoriок. ближайшей ночью не смогу (сбор урожая), ближе к понедельнику.выкладывай, интересно
А как тогда понять вот это:а про какую "блокировку PHP" речь?
PHP ждет только без &, без перенаправления вывода PHP все-равно свободен
А точнее фразу "ждем дочку"? Если PHP ничего не ждет, то кто ждет дочку или что под этим подразумевается?однако ...
system ( "/usr/local/bin/php sleep.php &" );
ждем дочку
реализовано через popen(); http://svn.php.net/viewvc/php/php-src/trunk/ext/standard/exec.c?view=markupПойду ка я пожалуй посмотрю, как в PHP на самом деле system реализован.
89 [b]stream = php_stream_fopen_from_pipe(fp, "rb");[/b]
90
91 buf = (char *) emalloc(EXEC_INPUT_BUF);
92 buflen = EXEC_INPUT_BUF;
93
94 if (type != 3) {
95 b = buf;
96
97 while ([b]php_stream_get_line(stream, ZSTR(b), EXEC_INPUT_BUF, &bufl)[/b]) {
98 /* no new line found, let's read some more */
99 if (b[bufl - 1] != '\n' && ![b]php_stream_eof(stream)[/b]) {
100 if (buflen < (bufl + (b - buf) + EXEC_INPUT_BUF)) {
101 bufl += b - buf;
102 buflen = bufl + EXEC_INPUT_BUF;
103 buf = erealloc(buf, buflen);
104 b = buf + bufl;
105 } else {
106 b += bufl;
107 }
108 continue;
109 } else if (b != buf) {
110 bufl += b - buf;
111 }
112
113 if (type == 1) {
114 int ob_level;
115 PHPWRITE(buf, bufl);
116 if ((php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL, &ob_level TSRMLS_CC) == SUCCESS) && ob_level < 1) {
117 sapi_flush(TSRMLS_C);
118 }
119 } else if (type == 2) {
120 /* strip trailing whitespaces */
121 l = bufl;
122 while (l-- && isspace(((unsigned char *)buf)[l]));
123 if (l != (bufl - 1)) {
124 bufl = l + 1;
125 buf[bufl] = '\0';
126 }
127 add_next_index_stringl(array, buf, bufl, 1);
128 }
129 b = buf;
130 }
131 if (bufl) {
132 /* strip trailing whitespaces if we have not done so already */
133 if (type != 2) {
134 l = bufl;
135 while (l-- && isspace(((unsigned char *)buf)[l]));
136 if (l != (bufl - 1)) {
137 bufl = l + 1;
138 buf[bufl] = '\0';
139 }
140 }
141
142 /* Return last line from the shell command */
143 RETVAL_STRINGL(buf, bufl, 1);
144 } else { /* should return NULL, but for BC we return "" */
145 RETVAL_EMPTY_STRING();
146 }
147 } else {
148 while((bufl = [b]php_stream_read(stream, buf, EXEC_INPUT_BUF)[/b]) > 0) {
149 PHPWRITE(buf, bufl);
150 }
151 }
152
153 [b]pclose_return = php_stream_close(stream);[/b]
154 efree(buf);
иPHP все-равно свободен
Кто кого ждет то и как это выражается?ждем дочку
Тогда все верно. В случае если не перенаправить вывод запускаемого процесса куда-либо он заблокирует php.я ошибся. воркер занят, ждет возврата
75 #if PHP_SIGCHILD
76 sig_handler = signal (SIGCHLD, SIG_DFL);
77 #endif
...
157 #if PHP_SIGCHILD
158 if (sig_handler) {
159 signal(SIGCHLD, sig_handler);
160 }
161 #endif