[C++] Apache/PHP process
Модератор: Fastman
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
-
- проходил мимо
- Сообщения: 6
- Зарегистрирован: 2010-07-30 12:51:47
[C++] Apache/PHP process
Я написал PHP etension модуль, который создает объект. Мне нужно reuse-ать этот объект между последовательными запросами от WEB-application. Windows/Apache/PHP работает, а вот Linux/Apache/PHP кажется использует разные процессы для обработки (или создает каждый раз новый процесс), поэтому второй запрос не видит объект созданный предыдущим. Есть ли способ сконфигурировать Linux/Apache/PHP, так чтобы запросами от WEB-application (это разные PHP сктипты) всегда обрабатывались одним и тем же процессом и этот прцесс бы жил пока WEB-application не logout-нулась.
Поможет ли httpd.worker model? /etc/sysconfig/httpd говорит, что httpd.worker model нельзя использовать с PHP.
Поможет ли httpd.worker model? /etc/sysconfig/httpd говорит, что httpd.worker model нельзя использовать с PHP.
Услуги хостинговой компании Host-Food.ru
Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/
- ProFTP
- подполковник
- Сообщения: 3388
- Зарегистрирован: 2008-04-13 1:50:04
- Откуда: %&й
- Контактная информация:
Re: Apache/PHP process
что-то не понятно, это типо многопоточность или взаимодействие с нексколькими сриптами
-
- проходил мимо
- Сообщения: 6
- Зарегистрирован: 2010-07-30 12:51:47
Re: Apache/PHP process
1. Скажем есть WEB-application с 2-мя запрсами к серверу. По первому запросу на сервере выполняется РНР скрипт 1, а по-второму – скрипт 2.
2. На сервере, есть РНР etension модуль написанный на С++.
3. Скрипты 1 и 2 используют функции этого С++ модуля.
4. В РНР etension модуле есть С++ GLOBAL МАР, кокторый хранит указатели на объекты.
5. Указатель от скрипта к скрипту передается через WEB-application.
Первый скрипт вызывает функцию 1, которая создает объект и добавляет указатель на этот объект в МАР.
Второй скрипт вызывает функцию 2, которая должна использовать этот объект. Так вот скрипт 2 не видит указатель созданный скриптом 1 (GLOBAL МАР пустой).
Я новичок с РНР etension модулями, РНР и Апачем.
Поэтому вопросы:
Можно ли и сделать С++ GLOBAL МАР общим для скриптов?
Еслп да, можно ли и сделать объект созданный первым скриптом видимым из 2-го скрипта?
Если да, то что может быть не так в РНР etension модуле? Или в конфигурации Апача?
Если нет, то надо организовывать интер-процесс communication, чего очень не хочется.
2. На сервере, есть РНР etension модуль написанный на С++.
3. Скрипты 1 и 2 используют функции этого С++ модуля.
4. В РНР etension модуле есть С++ GLOBAL МАР, кокторый хранит указатели на объекты.
5. Указатель от скрипта к скрипту передается через WEB-application.
Первый скрипт вызывает функцию 1, которая создает объект и добавляет указатель на этот объект в МАР.
Второй скрипт вызывает функцию 2, которая должна использовать этот объект. Так вот скрипт 2 не видит указатель созданный скриптом 1 (GLOBAL МАР пустой).
Я новичок с РНР etension модулями, РНР и Апачем.
Поэтому вопросы:
Можно ли и сделать С++ GLOBAL МАР общим для скриптов?
Еслп да, можно ли и сделать объект созданный первым скриптом видимым из 2-го скрипта?
Если да, то что может быть не так в РНР etension модуле? Или в конфигурации Апача?
Если нет, то надо организовывать интер-процесс communication, чего очень не хочется.
- ProFTP
- подполковник
- Сообщения: 3388
- Зарегистрирован: 2008-04-13 1:50:04
- Откуда: %&й
- Контактная информация:
Re: Apache/PHP process
давайте вы покажите код С++, и тему мы перенесем в рздел С++? 

- ProFTP
- подполковник
- Сообщения: 3388
- Зарегистрирован: 2008-04-13 1:50:04
- Откуда: %&й
- Контактная информация:
Re: [C++] Apache/PHP process
PS: вообще, есть SysV, IPC для взаимодействия скриптов, т.к. семафоры, share memory, и т.д. ... специально сделанное для межпроцессорного взамодействия
-
- проходил мимо
- Сообщения: 6
- Зарегистрирован: 2010-07-30 12:51:47
Re: [C++] Apache/PHP process
Вот код. Я постарался выбросить все лишнее.
А вот как я собирался использовать.
Скрипт 1:
Значение $nSessionID передается скрипту 2:
Код: Выделить всё
// db_extphp.cpp
//
#include <Qt/qglobal.h>
#include <QMap>
#include <QString>
#include "lib_db.h"//the CDb object is defined in this library
#ifdef DB_EXT_LIB
# define DB_EXT_EXPORT Q_DECL_EXPORT
#else
# define DB_EXT_EXPORT Q_DECL_IMPORT
#endif
//constants to export
#define DB_EXT_RETURN_VALUE "ReturnValue"
#define DB_EXT_ERROR_DESCRIPTION "ErrorDescription"
class DB_EXT_EXPORT CSelector : public QObject
{
Q_OBJECT
public:
CSelector(){};
~CSelector(){};
QMutex m_mutexDelete;
CDb m_objDB;//logic is in this object
};
class DB_EXT_EXPORT CConnections : public QObject
{
Q_OBJECT
public:
CConnections(){};
~CConnections();
long GetSessionID(char *sUser, char *sPswd, char *sDBHost, long nPort, char *sError);
QMutex m_mutexUseMap;
QMap<long,CSelector *> m_mapSessions;
};
CConnections::~CConnections()
{
QMap<long,CSelector *>::iterator pos;
for(pos=m_mapSessions.begin(); pos != m_mapSessions.end();)
{
try{
pos.value()->m_objDB.logoff();
}
catch(...){
}
try{
delete pos.value();
}
catch(...){
}
pos = m_mapSessions.erase(pos);
}
}
long CConnections::GetSessionID(char *sUser, char *sPswd, char *sDBHost, long nPort, char *sError)
{
long i,nID=0;
CSelector *pSelector=NULL;
pSelector=new CSelector;//new CDb object is created here
if(pSelector)
{
if(pSelector->m_objDB.login(sUser, sPswd, sDBHost, nPort))
{
nID = (long)time(NULL) * 0x9e3779b9;//create session code
for(i=0;i<2048;++i,++nID)
if(m_mapSessions.find(nID) == m_mapSessions.end())
break;
if(i<2048)
{
m_mutexUseMap.lock();
m_mapSessions.insert(nID, pSelector);
m_mutexUseMap.unlock();
}
else
{
nID=0;
delete pSelector;
strcpy(sError,"Too many open connections.");
}
}
else
{
strncpy(sError,pSelector->m_objDB.getLastError().toAscii().data(),255);
delete pSelector;
}
}
else
{
strcpy(sError,"Not enough memory.");
}
return nID;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
CConnections g_Connections;
#define GET_SELECTOR CSelector *pSelector=NULL;\
g_Connections.m_mutexUseMap.lock();\
pSelector = g_Connections.m_mapSessions.value(nSessionID);\
if(!pSelector){\
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong session ID.",1);\
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);\
g_Connections.m_mutexUseMap.unlock();\
return;\
}\
\
QMutexLocker locker(&pSelector->m_mutexDelete);\
g_Connections.m_mutexUseMap.unlock();\
\
#include "php.h"
ZEND_MODULE_STARTUP_D(DB_EXTPHP);
ZEND_MODULE_SHUTDOWN_D(DB_EXTPHP);
ZEND_FUNCTION(dbLogin);
ZEND_FUNCTION(dbLogout);
ZEND_FUNCTION(dbResetDataFields);
/* compiled function list so Zend knows what's in this module */
zend_function_entry DB_EXTPHP_functions[] = {
ZEND_FE(dbLogin, NULL)
ZEND_FE(dbLogout, NULL)
ZEND_FE(dbResetDataFields, NULL)
{NULL, NULL, NULL}
};
/* compiled module information */
zend_module_entry DB_EXTPHP_module_entry = {
STANDARD_MODULE_HEADER,
"DB_EXTPHP",
DB_EXTPHP_functions,
ZEND_MODULE_STARTUP_N(DB_EXTPHP),
ZEND_MODULE_SHUTDOWN_N(DB_EXTPHP),
NULL, NULL, NULL,
NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
};
/* implement standard "stub" routine to introduce ourselves to Zend */
ZEND_GET_MODULE(DB_EXTPHP)
ZEND_MODULE_STARTUP_D(DB_EXTPHP)
{
REGISTER_STRING_CONSTANT("DB_EXT_ERROR_DESCRIPTION", DB_EXT_ERROR_DESCRIPTION, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("DB_EXT_RETURN_VALUE", DB_EXT_RETURN_VALUE, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
ZEND_MODULE_SHUTDOWN_D(DB_EXTPHP)
{
return SUCCESS;
}
ZEND_FUNCTION(dbLogin){
char *sUser=NULL;
char *sPswd=NULL;//password
char *sDBHost=NULL;
long nUser;
long nDPswd;
long nDBHost;
long nPort;
long nSessionID;
char sError[256];
zval *pzResource;
CSelector *pSelector=NULL;
array_init(return_value);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssll",
&sUser, &nUser, &sPswd, &nDPswd, &sDBHost, &nDBHost, &nPort) == FAILURE){
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong parameters passed to the function.",1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
else{
if(!(nSessionID = g_Connections.GetSessionID(sUser,sPswd,sDBHost,nPort,sError))){
sError[255]=0;
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,sError,1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
else{
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"No error.",1);
add_assoc_long(return_value,DB_EXT_RETURN_VALUE,nSessionID);
}
}
}
ZEND_FUNCTION(dbLogout){
long nSessionID;
CSelector *pSelector=NULL;
array_init(return_value);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &nSessionID) == FAILURE){
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong parameters passed to the function.",1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
else{
g_Connections.m_mutexUseMap.lock();
pSelector = g_Connections.m_mapSessions.value(nSessionID);
g_Connections.m_mapSessions.remove(nSessionID);
g_Connections.m_mutexUseMap.unlock();
if(pSelector){
pSelector->m_objDB.logoff();
delete pSelector;
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"No error.",1);
add_assoc_long(return_value,DB_EXT_RETURN_VALUE,1);
}
else{
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong session ID.",1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
}
}
ZEND_FUNCTION(dbResetDataFields){
long nSessionID;
array_init(return_value);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &nSessionID) == FAILURE){
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong parameters passed to the function.",1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
return;//wrong parameters passed
}
//
GET_SELECTOR
//
pSelector->m_objDB.resetDBExtraction();
if(!pSelector->m_objDB.getLastError().isEmpty()){
char sError[256];
sError[255]=0;
strncpy(sError,pSelector->m_objDB.getLastError().toAscii().data(),255);
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,sError,1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
else{
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"No error.",1);
add_assoc_long(return_value,DB_EXT_RETURN_VALUE,1);
}
}
А вот как я собирался использовать.
Скрипт 1:
Код: Выделить всё
$hashResult = dbLogin($_POST['User'],$_POST['Password'],$_POST['Host'],$_POST['Port']);
if(is_null($hashResult[YE_RETURN_VALUE])){
echo '<br>';
exit ($hashResult[YE_ERROR_DESCRIPTION]);
}else {
$nSessionID = $hashResult[YE_RETURN_VALUE];
}
Код: Выделить всё
$hashResult = dbResetDataFields($nSessionID);
if(is_null($hashResult[YE_RETURN_VALUE])){
echo '<br>', $hashResult[YE_ERROR_DESCRIPTION];
}
dbLogout($nSessionID);
-
- проходил мимо
- Сообщения: 6
- Зарегистрирован: 2010-07-30 12:51:47
Re: [C++] Apache/PHP process
Пардон, кое-что забыл поменять, не суть, но все-таки...
Скрипт 1:
Скрипт 2:
Скрипт 1:
Код: Выделить всё
$hashResult = dbLogin($_POST['User'],$_POST['Password'],$_POST['Host'],$_POST['Port']);
if(is_null($hashResult[DB_EXT_RETURN_VALUE])){
echo '<br>';
exit ($hashResult[DB_EXT_ERROR_DESCRIPTION]);
}else {
$nSessionID = $hashResult[DB_EXT_RETURN_VALUE];
}
Код: Выделить всё
$hashResult = dbResetDataFields($nSessionID);
if(is_null($hashResult[DB_EXT_RETURN_VALUE])){
echo '<br>', $hashResult[DB_EXT_ERROR_DESCRIPTION];
}
dbLogout($nSessionID);
-
- ефрейтор
- Сообщения: 61
- Зарегистрирован: 2009-11-27 22:29:58
Re: [C++] Apache/PHP process
Как то странно вы пишите, в топике пишете про настройки апачей, в 3 сообщении код выставляете,решите в чём будете копаться.
У вас в нём кстати идёт проверка при перезагрузке, могли бы и рассказать что оно вам выдаёт)
"С++ GLOBAL МАР" не понятно мне(гугл с яндаксом тоже разводят руки), что это такое по вашему в приведённом примере кода не ясно, его просто нет.
map у вас единственный находится в вроде бы глобальном объекте g_Connections, в логине и логауте вы к нему обращаетесь и используете от туда сессии от m_mapSessions, а в функции рестарта вы используете не известно откуда взявшегося объекта(из приведённого кода) pSelector и с помощью его уже рестартите...
У вас в нём кстати идёт проверка при перезагрузке, могли бы и рассказать что оно вам выдаёт)
Код: Выделить всё
pSelector->m_objDB.resetDBExtraction();
if(!pSelector->m_objDB.getLastError().isEmpty()){
char sError[256];
sError[255]=0;
strncpy(sError,pSelector->m_objDB.getLastError().toAscii().data(),255);
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,sError,1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
map у вас единственный находится в вроде бы глобальном объекте g_Connections, в логине и логауте вы к нему обращаетесь и используете от туда сессии от m_mapSessions, а в функции рестарта вы используете не известно откуда взявшегося объекта(из приведённого кода) pSelector и с помощью его уже рестартите...
-
- проходил мимо
- Сообщения: 6
- Зарегистрирован: 2010-07-30 12:51:47
Re: [C++] Apache/PHP process
Извиняюсь за свою способность формулировать вопросы и постараюсь быть более понятным.
1. Скажем есть WEB-application с 2-мя запросами от клиента к серверу. По первому запросу на сервере выполняется РНР скрипт 1, а по-второму – скрипт 2.
2. На сервере, есть РНР extension модуль написанный на С++.
3. Скрипты 1 и 2 используют функции этого С++ модуля.
4. В РНР extension модуле есть есть глобальный объект g_Connections.
5. WEB-application обращается к серверу для выполнения Скрипт 1.
6. Скрипт 1 вызывает функцию dbLogin.
7. dbLogin вызывает функцию g_Connections.GetSessionID, которая создает CSelector объект и уникальный Id для этого объекта. А также заносит этот объект в g_Connections.m_mapSessions (смотри m_mapSessions.insert(nID, pSelector);). Уникальный Id возвращается в скрипт. Вся логика последующих запросов инкапсулирована в одном из членов CSelector (CDb).
8. Скрипт 1 возвращает уникальный Id в WEB-application клиенту.
9. На этом первое обращение клиента к серверу заканчивается. Объект создан, занесен в map и предполагается быть использован следующими запросами.
10. WEB-application обращается к серверу для выполнения Скрипт 2.
11. Скрипт 2 вызывает функцию dbResetDataFields с уникальным Id параметром полученным от Скрипт 1.
12. Функция dbResetDataFields пытается достать CSelector объект соответстующий этому уникальному Id
(смотри #define GET_SELECTOR макро сразу после CConnections g_Connections;
pSelector = g_Connections.m_mapSessions.value(nSessionID);)
13. На Windows сервере это работает. На Linux сервере
pSelector = g_Connections.m_mapSessions.value(nSessionID);
не находит CSelector объект соответстующий этому уникальному Id.
Я понимаю так: под Windows есть один апач процесс и много thread-ов, поэтому все хорошо. А под Linux есть много апач-процессов и первый скрипт был обработан одним процессом, а второй скрипт другим процессом и поэтом в каждом процессе есть свой глобальный объект CConnections g_Connections. Скрипт 1 в первом процессе добавляет CSelector объект g_Connections.m_mapSessions. А Скрипт 2 пытается достать этот обект из другого процесса и естественно не может.
Вопрос: Можно ли сделать так (сконфигурировать апач), чтобы все скрипты от данного клиента (WEB-application ) обрабатывались тем же апач процессом на Linux сервере.
1. Скажем есть WEB-application с 2-мя запросами от клиента к серверу. По первому запросу на сервере выполняется РНР скрипт 1, а по-второму – скрипт 2.
2. На сервере, есть РНР extension модуль написанный на С++.
3. Скрипты 1 и 2 используют функции этого С++ модуля.
4. В РНР extension модуле есть есть глобальный объект g_Connections.
5. WEB-application обращается к серверу для выполнения Скрипт 1.
6. Скрипт 1 вызывает функцию dbLogin.
7. dbLogin вызывает функцию g_Connections.GetSessionID, которая создает CSelector объект и уникальный Id для этого объекта. А также заносит этот объект в g_Connections.m_mapSessions (смотри m_mapSessions.insert(nID, pSelector);). Уникальный Id возвращается в скрипт. Вся логика последующих запросов инкапсулирована в одном из членов CSelector (CDb).
8. Скрипт 1 возвращает уникальный Id в WEB-application клиенту.
9. На этом первое обращение клиента к серверу заканчивается. Объект создан, занесен в map и предполагается быть использован следующими запросами.
10. WEB-application обращается к серверу для выполнения Скрипт 2.
11. Скрипт 2 вызывает функцию dbResetDataFields с уникальным Id параметром полученным от Скрипт 1.
12. Функция dbResetDataFields пытается достать CSelector объект соответстующий этому уникальному Id
(смотри #define GET_SELECTOR макро сразу после CConnections g_Connections;
pSelector = g_Connections.m_mapSessions.value(nSessionID);)
13. На Windows сервере это работает. На Linux сервере
pSelector = g_Connections.m_mapSessions.value(nSessionID);
не находит CSelector объект соответстующий этому уникальному Id.
Я понимаю так: под Windows есть один апач процесс и много thread-ов, поэтому все хорошо. А под Linux есть много апач-процессов и первый скрипт был обработан одним процессом, а второй скрипт другим процессом и поэтом в каждом процессе есть свой глобальный объект CConnections g_Connections. Скрипт 1 в первом процессе добавляет CSelector объект g_Connections.m_mapSessions. А Скрипт 2 пытается достать этот обект из другого процесса и естественно не может.
Вопрос: Можно ли сделать так (сконфигурировать апач), чтобы все скрипты от данного клиента (WEB-application ) обрабатывались тем же апач процессом на Linux сервере.
-
- ефрейтор
- Сообщения: 61
- Зарегистрирован: 2009-11-27 22:29:58
Re: [C++] Apache/PHP process
Не в том форуме пишите вопрос, утилитой ps(почитайте man ps или http://ru.wikipedia.org/wiki/Ps,Вопрос: Можно ли сделать так (сконфигурировать апач), чтобы все скрипты от данного клиента (WEB-application ) обрабатывались тем же апач процессом на Linux сервере.
конкретно для фряхи http://www.freebsd.org/cgi/man.cgi?query=ps&sektion=1) можно посмотреть процессы запущенные на сервере, это по поводу количества апачевых процессов.
По поводу решения проблемы могу посоветовать только, создания приложения.
Заранее запущенного на сервере или сделать проверку в 1 скрипте на запуск, а скриптом 2 посылать сигнал с идентификатором, вы всё равно используете qt, сигналы и процессы в ней реализовать очень просто.
- BlackCat
- прапорщик
- Сообщения: 469
- Зарегистрирован: 2007-10-16 22:40:42
Re: [C++] Apache/PHP process
Присоединюсь к Dambo.
Не сохранение данных между запросами - это фундаментальная особенность скриптовых языков и нарушать её - не самая лучшая идея. Это заложено ещё в HTTP-протоколе, где клиент по мере необходимости обращается к серверу, а не подключен постоянно. Постоянное соединение (сессия) - это всего лишь абстракция.
Если данные требуется сохранять между запросами, то для этого используют сессии и сериализацию данных. Если по каким-либо причинам такой вариант не подходит, то необходимо писать свой демон. Он или сам будет обрабатывать все запросы пользователей (т.е. реализовывать HTTP-протокол) или в качестве фронтенда должен использоваться какой-то HTTP-сервер (прим. Apache), связывающийся с вашим демоном при обработке запросов пользователей.
Не сохранение данных между запросами - это фундаментальная особенность скриптовых языков и нарушать её - не самая лучшая идея. Это заложено ещё в HTTP-протоколе, где клиент по мере необходимости обращается к серверу, а не подключен постоянно. Постоянное соединение (сессия) - это всего лишь абстракция.
Если данные требуется сохранять между запросами, то для этого используют сессии и сериализацию данных. Если по каким-либо причинам такой вариант не подходит, то необходимо писать свой демон. Он или сам будет обрабатывать все запросы пользователей (т.е. реализовывать HTTP-протокол) или в качестве фронтенда должен использоваться какой-то HTTP-сервер (прим. Apache), связывающийся с вашим демоном при обработке запросов пользователей.
-
- проходил мимо
- Сообщения: 6
- Зарегистрирован: 2010-07-30 12:51:47
Re: [C++] Apache/PHP process
Я понял. Спасибо за информацию.