windows下php-cgi进程守护
Jun 06, 2016 pm 07:31 PMphp在linux,unix下有php-fpm,spawn-fcgi等进程守护程序,但是在window下没有。 一般会以下命令启动C:/php5/php-cgi.exe-b127.0.0.1:9000-cC:/php5/php.ini 但是这样受限于php-cgi的PHP_FCGI_MAX_REQUESTS环境变量,默认处理500次后自动退出php-cgi.加之一些非
php在linux,unix下有php-fpm,spawn-fcgi等进程守护程序,但是在window下没有。
一般会以下命令启动 C:/php5/php-cgi.exe -b 127.0.0.1:9000 -c C:/php5/php.ini
但是这样受限于php-cgi的PHP_FCGI_MAX_REQUESTS环境变量,默认处理500次后自动退出php-cgi.加之一些非正常原因的异常退出,都会导致php-cgi.exe的退出。所有在window需要进程守护程序,当php-cgi退出后自动打开新的php-cgi进程。
注意事项:windows建议关闭Dr. Watson,否则 异常的php-cgi无法正常退出。
http://support.microsoft.com/kb/188296/zh-cn
// FastCGIHelper.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #pragma comment(lib, "ws2_32.lib") const PCHAR cServiceName="WinFastCGIHelper"; HANDLE hJob; INT icount; INT iport; CHAR ipbuf[32]; CHAR cmdbuf[256]; //--------------------------------------------------------------------------- SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE hStatus; void Install(void); void Uninstall(void); void ServiceMain(int argc, char** argv); void ThreadProc(LPVOID pParam); void ControlHandler(DWORD request); //--------------------------------------------------------------------------- int _tmain(int argc, _TCHAR* argv[]) { if (argc>1 && _stricmp(argv[1],"/i")==0) { Install(); } else if (argc>1 && _stricmp(argv[1],"/u")==0) { Uninstall(); } else { SERVICE_TABLE_ENTRY ServiceTable[2]; ServiceTable[0].lpServiceName = cServiceName; ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[1].lpServiceName = NULL; ServiceTable[1].lpServiceProc = NULL; ::StartServiceCtrlDispatcher(ServiceTable); } return 0; } void ServiceMain(int argc, char** argv) { ServiceStatus.dwServiceType =SERVICE_WIN32; ServiceStatus.dwCurrentState =SERVICE_START_PENDING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; hStatus = ::RegisterServiceCtrlHandler(cServiceName, (LPHANDLER_FUNCTION)ControlHandler); if (hStatus == NULL) return; if (GetLastError()!=NO_ERROR) { ServiceStatus.dwCurrentState = SERVICE_STOPPED; ::SetServiceStatus(hStatus, &ServiceStatus); return; } CHAR cConfigName[256]; ZeroMemory(cConfigName,256); DWORD dwSize=GetModuleFileName(NULL,cConfigName,256); while(dwSize>0 && cConfigName[dwSize]!='\\') cConfigName[dwSize--]=0; strcat_s(cConfigName,"config.ini"); icount=GetPrivateProfileInt("setup","CmdCount",1,cConfigName); GetPrivateProfileString("setup","CmdPath","",cmdbuf,256,cConfigName); if(icount<1) icount=1; if(icount>32) icount=32; iport =GetPrivateProfileInt("setup","Port",9000,cConfigName); GetPrivateProfileString("setup","IP","127.0.0.1",ipbuf,32,cConfigName); WSADATA wsa_data; WSAStartup(0x0202, &wsa_data); SOCKADDR_IN listen_addr; listen_addr.sin_family =AF_INET; listen_addr.sin_addr.S_un.S_addr= inet_addr(ipbuf); listen_addr.sin_port = htons(iport); DWORD s=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if(bind(s, (struct sockaddr*)&listen_addr, sizeof(struct sockaddr_in)) || listen(s,16) ){ ServiceStatus.dwCurrentState = SERVICE_STOPPED; ::SetServiceStatus(hStatus, &ServiceStatus); return; } CHAR strtmp[128]; ZeroMemory(strtmp,128); GetPrivateProfileString("env","PHPRC",".",strtmp,127,cConfigName); SetEnvironmentVariable("PHPRC",strtmp); GetPrivateProfileString("env","PHP_FCGI_MAX_REQUESTS","5000",strtmp,127,cConfigName); SetEnvironmentVariable("PHP_FCGI_MAX_REQUESTS",strtmp); hJob=CreateJobObject(NULL,NULL); JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit; QueryInformationJobObject(hJob, JobObjectExtendedLimitInformation, &limit, sizeof(limit), NULL); limit.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &limit, sizeof(limit)); ServiceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(hStatus, &ServiceStatus); for(int i=0;i<icount;i++) CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,(LPVOID)s,0,0)); WaitForSingleObject(hJob, INFINITE); closesocket(s); WSACleanup(); ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hStatus, &ServiceStatus); } //--------------------------------------------------------------------------- void ThreadProc(LPVOID pParam) { STARTUPINFO si; PROCESS_INFORMATION pi; while(ServiceStatus.dwCurrentState == SERVICE_RUNNING) { ZeroMemory(&si,sizeof(STARTUPINFO)); ZeroMemory(&pi,sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = (HANDLE)pParam; si.hStdOutput = INVALID_HANDLE_VALUE; si.hStdError = INVALID_HANDLE_VALUE; if(0==CreateProcess(NULL,cmdbuf,NULL,NULL,TRUE, CREATE_NO_WINDOW | CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB ,NULL,NULL,&si,&pi)) break; AssignProcessToJobObject(hJob, pi.hProcess); ResumeThread(pi.hThread); WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle( pi.hProcess); CloseHandle( pi.hThread ); } } //--------------------------------------------------------------------------- void ControlHandler(DWORD request) { switch(request) { case SERVICE_CONTROL_STOP: ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hStatus, &ServiceStatus); CloseHandle(hJob); return; case SERVICE_CONTROL_SHUTDOWN: ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hStatus, &ServiceStatus); CloseHandle(hJob); return; } ::SetServiceStatus (hStatus, &ServiceStatus); } //--------------------------------------------------------------------------- void Install(void) { char szFilePath[256]; SC_HANDLE hSCM,hService; ZeroMemory(szFilePath,256); GetModuleFileName(NULL,szFilePath,256); hSCM=::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); SC_LOCK sclLock = LockServiceDatabase(hSCM); hService = ::CreateService( hSCM, cServiceName, cServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szFilePath, NULL, NULL,NULL, NULL, NULL); SERVICE_DESCRIPTION sdBuf; sdBuf.lpDescription = "php fastcgi process helper for windows"; ChangeServiceConfig2(hService,SERVICE_CONFIG_DESCRIPTION,&sdBuf); ::CloseServiceHandle(hService); ::UnlockServiceDatabase(sclLock); ::CloseServiceHandle(hSCM); printf("Service Install OK !!!"); } //--------------------------------------------------------------------------- void Uninstall(void) { SERVICE_STATUS sStatus ; SC_HANDLE hSCM=::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); SC_HANDLE hService=::OpenService(hSCM, cServiceName, SERVICE_STOP | DELETE); if (hService==NULL) { printf("Service Open Error !!!"); } else { ::ControlService(hService, SERVICE_CONTROL_STOP, &sStatus); ::DeleteService(hService); printf("Service Uninstall OK !!!"); } ::CloseServiceHandle(hService); ::CloseServiceHandle(hSCM); } //---------------------------------------------------------------------------

Heißer Artikel

Hot-Tools-Tags

Heißer Artikel

Heiße Artikel -Tags

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

PHP 8.4 Installations- und Upgrade-Anleitung für Ubuntu und Debian

Wie aktualisiere ich die neueste Version von Bybit Exchange? Wird es Auswirkungen geben, wenn es nicht aktualisiert wird?

Deepseek Web Version Eingang Deepseek Offizielle Website Eingang

PI -Knotenunterricht: Was ist ein PI -Knoten? Wie installiere und richte ich einen PI -Knoten ein?

So richten Sie Visual Studio-Code (VS-Code) für die PHP-Entwicklung ein

Wie analysiert und verarbeitet man HTML/XML in PHP?

Offizieller Eingang des offiziellen Website des Coinsuper Exchange Software Channel
