int cpWorker_manager_loop() { int pid; int worker_exit_code; //reload config cpSignalSet(SIGUSR1, cpManagerReload, 1, 0); //close worker cpSignalSet(SIGALRM, cpManagerRecycle, 1, 0); //add one worker cpSignalSet(SIGRTMIN, cpManagerAdd, 1, 0); alarm(2); sigset_t block_alarm; sigemptyset(&block_alarm); sigaddset(&block_alarm, SIGALRM); sigaddset(&block_alarm, SIGRTMIN); sigaddset(&block_alarm, SIGUSR1); while (CPGS->running == 1) { pid = wait(&worker_exit_code); sigprocmask(SIG_BLOCK, &block_alarm, NULL); if (CPGS->running == 1 && pid > 0) { if (pid == CPGS->ping_workers->pid) { cpLog("ping worker exit"); int ping_pid = cpFork_ping_worker(); if (ping_pid < 0) { cpLog("Fork ping process fail"); } else { CPGS->ping_workers->pid = ping_pid; } } cpFind_restart_worker(pid, &block_alarm, worker_exit_code); } sigprocmask(SIG_UNBLOCK, &block_alarm, NULL); } return SUCCESS; }
int cpServer_start() { int i, pid, ret, ping_pid, sock; if (CPGC.daemonize > 0) { if (daemon(0, 0) < 0) { return FAILURE; } } if ((sock = cpListen()) < 0) { cpLog("listen[1] fail"); return FAILURE; } CPGS->master_pid = getpid(); CPGL.process_type = CP_PROCESS_MASTER; cpList_create(); pid = fork(); switch (pid) { //创建manager进程 case 0: for (i = 0; i < CPGC.worker_min; i++) { //alloc了max个 但是只启动min个 ret = cpCreate_worker_mem(i); pid = cpFork_one_worker(i); if (pid < 0 || ret < 0) { cpLog("Fork worker process fail"); return FAILURE; } else { CPGS->workers[i].pid = pid; CPGS->workers_status[i] = CP_WORKER_IDLE; } } //数据库坏连接检测恢复进程 ret = cpCreate_ping_worker_mem(); ping_pid = cpFork_ping_worker(); if (ping_pid < 0 || ret < 0) { cpLog("Fork ping process fail"); return FAILURE; } CPGS->ping_workers->pid = ping_pid; //标识为管理进程 CPGL.process_type = CP_PROCESS_MANAGER; CPGS->worker_num = CPGC.worker_min; //初始为min个worker ret = cpWorker_manager_loop(); exit(ret); break; //主进程 default: CPGS->manager_pid = pid; break; case -1: { cpLog("fork manager process fail"); return FAILURE; } } cpSignalInit(); if (cpReactor_start(sock) < 0) { cpLog("Reactor_start[1] fail"); return FAILURE; } return SUCCESS; }
int cpWorker_manager_loop() { int pid, new_pid; int i; int worker_exit_code; //reload config cpSignalSet(SIGUSR1, cpManagerReload, 1, 0); //close worker cpSignalSet(SIGALRM, cpManagerRecycle, 1, 0); //add one worker cpSignalSet(SIGRTMIN, cpManagerAdd, 1, 0); alarm(2); sigset_t block_alarm; sigemptyset(&block_alarm); sigaddset(&block_alarm, SIGALRM); sigaddset(&block_alarm, SIGRTMIN); sigaddset(&block_alarm, SIGUSR1); while (CPGS->running == 1) { pid = wait(&worker_exit_code); sigprocmask(SIG_BLOCK, &block_alarm, NULL); if (CPGS->running == 1 && pid > 0) { if (pid == CPGS->ping_workers->pid) { cpLog("ping worker exit"); int ping_pid = cpFork_ping_worker(); if (ping_pid < 0) { cpLog("Fork ping process fail"); } else { CPGS->ping_workers->pid = ping_pid; } } for (i = CPGS->worker_num; i >= 0; i--) { if (pid != CPGS->workers[i].pid || CPGS->workers_status[i] == CP_WORKER_DEL) {//对比pid||回收的不拉起 continue; } else { if (CPGS->workers[i].run == 0) { cpLog("restart worker!worker index %d,worker id %d,exit code %d\n", i, pid, WEXITSTATUS(worker_exit_code)); } else { cpLog("worker exit!worker index %d,worker id %d,exit code %d,times %d,pre_len %d\n", i, pid, WEXITSTATUS(worker_exit_code), CPGS->workers[i].request, CPGS->workers[i].pre_len); } cpShareMemory *sm_obj = &(CPGS->workers[i].sm_obj); sm_obj->mem = NULL; pid = 0; new_pid = cpFork_one_worker(i); if (new_pid < 0) { cpLog("Fork worker process failed. Error: %s [%d]", strerror(errno), errno); sigprocmask(SIG_UNBLOCK, &block_alarm, NULL); return FAILURE; } else { CPGS->workers[i].pid = new_pid; } } } } sigprocmask(SIG_UNBLOCK, &block_alarm, NULL); } return SUCCESS; }