//create worker child proccess static int swFactoryProcess_worker_start(swFactory *factory) { swFactoryProcess *this = factory->object; int i, ret = 0; for (i = 0; i < this->worker_num; i++) { printf("[Main]spawn worker processor\n"); ret = swFactoryProcess_worker_spawn(factory, (i % this->writer_num), i); } return SW_OK; }
static int swFactoryProcess_manager_loop(swFactory *factory) { int pid, new_pid; int i, writer_pti; int reload_worker_i = 0; int ret; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; swWorker *reload_workers; reload_workers = sw_calloc(object->worker_num, sizeof(swWorker)); if (reload_workers == NULL) { swError("[manager] malloc[reload_workers] fail.\n"); return SW_ERR; } //for reload swSignalSet(SIGUSR1, swManagerSignalHanlde, 1, 0); while (swoole_running > 0) { pid = wait(NULL); swTrace("[manager] worker stop.pid=%d\n", pid); if (pid < 0) { if (manager_worker_reloading == 0) { swTrace("[Manager] wait fail. Error: %s [%d]", strerror(errno), errno); } else if (manager_reload_flag == 0) { memcpy(reload_workers, object->workers, sizeof(swWorker) * object->worker_num); manager_reload_flag = 1; goto kill_worker; } } if (swoole_running == 1) { for (i = 0; i < object->worker_num; i++) { //对比pid if (pid != object->workers[i].pid) { continue; } else { pid = 0; new_pid = swFactoryProcess_worker_spawn(factory, i); if (new_pid < 0) { swWarn("Fork worker process fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } else { object->workers[i].pid = new_pid; } } } //task worker if(pid > 0) { swWorker *exit_worker = swHashMap_find_int(&SwooleG.task_workers.map, pid); if (exit_worker != NULL) { swProcessPool_spawn(&SwooleG.task_workers, exit_worker); } } } //reload worker kill_worker: if (manager_worker_reloading == 1) { //reload finish if (reload_worker_i >= object->worker_num) { manager_worker_reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swWarn("[Manager]kill fail.pid=%d. Error: %s [%d]", reload_workers[reload_worker_i].pid, strerror(errno), errno); continue; } reload_worker_i++; } } sw_free(reload_workers); return SW_OK; }
//create worker child proccess static int swFactoryProcess_manager_start(swFactory *factory) { swFactoryProcess *object = factory->object; int i, pid, ret; int writer_pti; swServer *serv = factory->ptr; #if SW_WORKER_IPC_MODE == 2 #define _SW_PATH_BUF_LEN 128 //这里使用ftok来获取消息队列的key char path_buf[_SW_PATH_BUF_LEN]; char *path_ptr = getcwd(path_buf, _SW_PATH_BUF_LEN); //读数据队列 if(swQueueMsg_create(&object->rd_queue, 1, ftok(path_ptr, 1), 1) < 0) { swError("[Master] swPipeMsg_create[In] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } //为TCP创建写队列 if (serv->have_tcp_sock == 1) { //写数据队列 if(swQueueMsg_create(&object->wt_queue, 1, ftok(path_ptr, 2), 1) < 0) { swError("[Master] swPipeMsg_create[out] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } } #else object->pipes = sw_calloc(object->worker_num, sizeof(swPipe)); if (object->pipes == NULL) { swError("malloc[worker_pipes] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } //worker进程的pipes for (i = 0; i < object->worker_num; i++) { if (swPipeUnsock_create(&object->pipes[i], 1, SOCK_DGRAM) < 0) { swError("create unix socket[1] fail"); return SW_ERR; } object->workers[i].pipe_master = object->pipes[i].getFd(&object->pipes[i], 1); object->workers[i].pipe_worker = object->pipes[i].getFd(&object->pipes[i], 0); } #endif if (serv->task_worker_num > 0) { if (swProcessPool_create(&SwooleG.task_workers, serv->task_worker_num, serv->max_request)< 0) { swWarn("[Master] create task_workers fail"); return SW_ERR; } //设置指针和回调函数 SwooleG.task_workers.ptr = serv; SwooleG.task_workers.onTask = swTaskWorker_onTask; } pid = fork(); switch (pid) { //创建manager进程 case 0: for (i = 0; i < object->worker_num; i++) { // close(worker_pipes[i].pipes[0]); writer_pti = (i % object->writer_num); object->workers[i].writer_id = writer_pti; pid = swFactoryProcess_worker_spawn(factory, i); if (pid < 0) { swError("Fork worker process fail"); return SW_ERR; } else { object->workers[i].pid = pid; } } //创建task_worker进程 if (serv->task_worker_num > 0) { swProcessPool_start(&SwooleG.task_workers); } //标识为管理进程 SwooleG.process_type = SW_PROCESS_MANAGER; ret = swFactoryProcess_manager_loop(factory); exit(ret); break; //主进程 default: object->manager_pid = pid; //TCP需要writer线程 if (serv->have_tcp_sock == 1) { int ret = swFactoryProcess_writer_start(factory); if (ret < 0) { return SW_ERR; } } #if SW_WORKER_IPC_MODE != 2 for (i = 0; i < object->worker_num; i++) { writer_pti = (i % object->writer_num); object->workers[i].writer_id = writer_pti; if (serv->have_tcp_sock == 1) { //将写pipe设置到writer的reactor中 object->writers[writer_pti].reactor.add(&(object->writers[writer_pti].reactor), object->workers[i].pipe_master, SW_FD_PIPE); } } #endif break; case -1: swError("[swFactoryProcess_worker_start]fork manager process fail\n"); return SW_ERR; } return SW_OK; }
static int swFactoryProcess_manager_loop(swFactory *factory) { int pid, new_pid; int i; int reload_worker_i = 0; int ret; int worker_exit_code; SwooleG.use_signalfd = 0; SwooleG.use_timerfd = 0; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; swWorker *reload_workers; if (serv->onManagerStart) { serv->onManagerStart(serv); } reload_workers = sw_calloc(serv->worker_num, sizeof(swWorker)); if (reload_workers == NULL) { swError("[manager] malloc[reload_workers] failed"); return SW_ERR; } //for reload swSignal_add(SIGUSR1, swManagerSignalHanlde); while (SwooleG.running > 0) { pid = wait(&worker_exit_code); swTrace("[manager] worker stop.pid=%d\n", pid); if (pid < 0) { if (manager_worker_reloading == 0) { swTrace("[Manager] wait failed. Error: %s [%d]", strerror(errno), errno); } else if (manager_reload_flag == 0) { memcpy(reload_workers, object->workers, sizeof(swWorker) * serv->worker_num); manager_reload_flag = 1; goto kill_worker; } } if (SwooleG.running == 1) { for (i = 0; i < serv->worker_num; i++) { //对比pid if (pid != object->workers[i].pid) { continue; } else { if(serv->onWorkerError!=NULL && WEXITSTATUS(worker_exit_code) > 0) { serv->onWorkerError(serv, i, pid, WEXITSTATUS(worker_exit_code)); } pid = 0; new_pid = swFactoryProcess_worker_spawn(factory, i); if (new_pid < 0) { swWarn("Fork worker process failed. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } else { object->workers[i].pid = new_pid; } } } //task worker if(pid > 0) { swWorker *exit_worker = swHashMap_find_int(&SwooleG.task_workers.map, pid); if (exit_worker != NULL) { swProcessPool_spawn(exit_worker); } } } //reload worker kill_worker: if (manager_worker_reloading == 1) { //reload finish if (reload_worker_i >= serv->worker_num) { manager_worker_reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swWarn("[Manager]kill failed, pid=%d. Error: %s [%d]", reload_workers[reload_worker_i].pid, strerror(errno), errno); continue; } reload_worker_i++; } } sw_free(reload_workers); if (serv->onManagerStop) { serv->onManagerStop(serv); } return SW_OK; }
//create worker child proccess static int swFactoryProcess_manager_start(swFactory *factory) { swFactoryProcess *object = factory->object; int i, pid, ret; int reactor_pti; swServer *serv = factory->ptr; if (serv->ipc_mode == SW_IPC_MSGQUEUE) { //读数据队列 if (swQueueMsg_create(&object->rd_queue, 1, serv->message_queue_key, 1) < 0) { swError("[Master] swPipeMsg_create[In] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } //为TCP创建写队列 if (serv->have_tcp_sock == 1) { //写数据队列 if (swQueueMsg_create(&object->wt_queue, 1, serv->message_queue_key + 1, 1) < 0) { swError("[Master] swPipeMsg_create[out] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } } } else { object->pipes = sw_calloc(serv->worker_num, sizeof(swPipe)); if (object->pipes == NULL) { swError("malloc[worker_pipes] fail. Error: %s [%d]", strerror(errno), errno); return SW_ERR; } //worker进程的pipes for (i = 0; i < serv->worker_num; i++) { if (swPipeUnsock_create(&object->pipes[i], 1, SOCK_DGRAM) < 0) { swError("create unix socket[1] fail"); return SW_ERR; } object->workers[i].pipe_master = object->pipes[i].getFd(&object->pipes[i], 1); object->workers[i].pipe_worker = object->pipes[i].getFd(&object->pipes[i], 0); } } if (SwooleG.task_worker_num > 0) { key_t msgqueue_key = 0; if (SwooleG.task_ipc_mode > 0) { msgqueue_key = serv->message_queue_key + 2; } if (swProcessPool_create(&SwooleG.task_workers, SwooleG.task_worker_num, serv->max_request, msgqueue_key)< 0) { swWarn("[Master] create task_workers fail"); return SW_ERR; } //设置指针和回调函数 SwooleG.task_workers.ptr = serv; SwooleG.task_workers.onTask = swTaskWorker_onTask; if (serv->onWorkerStart != NULL) { SwooleG.task_workers.onWorkerStart = swTaskWorker_onWorkerStart; } } pid = fork(); switch (pid) { //创建manager进程 case 0: //创建子进程 for (i = 0; i < serv->worker_num; i++) { //close(worker_pipes[i].pipes[0]); reactor_pti = (i % serv->writer_num); object->workers[i].reactor_id = reactor_pti; pid = swFactoryProcess_worker_spawn(factory, i); if (pid < 0) { swError("Fork worker process fail"); return SW_ERR; } else { object->workers[i].pid = pid; } } /** * create task worker pool */ if (SwooleG.task_worker_num > 0) { swProcessPool_start(&SwooleG.task_workers); } //标识为管理进程 SwooleG.process_type = SW_PROCESS_MANAGER; ret = swFactoryProcess_manager_loop(factory); exit(ret); break; //主进程 default: SwooleGS->manager_pid = pid; break; case -1: swError("[swFactoryProcess_worker_start]fork manager process fail"); return SW_ERR; } return SW_OK; }
static int swFactoryProcess_manager_loop(swFactory *factory) { int pid, new_pid; int i, writer_pti; int reload_worker_i = 0; int ret; swFactoryProcess *this = factory->object; swWorkerChild *reload_workers; reload_workers = sw_calloc(this->worker_num, sizeof(swWorkerChild)); if (reload_workers == NULL ) { swError("[manager] malloc[reload_workers] fail.\n"); return SW_ERR; } //for reload swSignalSet(SIGUSR1, swManagerSignalHanlde, 1, 0); while (1) { pid = wait(NULL ); swTrace("[manager] worker stop.pid=%d\n", pid); if (pid < 0) { if (manager_worker_reloading == 0) { swTrace("wait fail.errno=%d\n", errno); } else if (manager_reload_flag == 0) { memcpy(reload_workers, this->workers, sizeof(swWorkerChild) * this->worker_num); manager_reload_flag = 1; goto kill_worker; } } for (i = 0; i < this->worker_num; i++) { if (pid != this->workers[i].pid) continue; writer_pti = (i % this->writer_num); new_pid = swFactoryProcess_worker_spawn(factory, writer_pti, i); if (new_pid < 0) { swWarn("Fork worker process fail.Errno=%d\n", errno); return SW_ERR; } else { this->workers[i].pid = new_pid; } } //reload worker kill_worker: if (manager_worker_reloading == 1) { //reload finish if (reload_worker_i >= this->worker_num) { manager_worker_reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swWarn("kill fail.pid=%d|errno=%d\n", reload_workers[reload_worker_i].pid, errno); continue; } reload_worker_i++; } } return SW_OK; }
//create worker child proccess static int swFactoryProcess_worker_start(swFactory *factory) { swFactoryProcess *this = factory->object; int i, pid; swPipes *worker_pipes; int writer_pti; worker_pipes = sw_calloc(this->worker_num, sizeof(swPipes)); if (worker_pipes == NULL ) { swTrace("[swFactoryProcess_worker_start]malloc fail.Errno=%d\n", errno); return SW_ERR; } for (i = 0; i < this->worker_num; i++) { if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, worker_pipes[i].pipes) < 0) { swTrace("[swFactoryProcess_worker_start]create unix socket fail\n"); return SW_ERR; } } pid = fork(); switch (pid) { case 0: for (i = 0; i < this->worker_num; i++) { close(worker_pipes[i].pipes[0]); writer_pti = (i % this->writer_num); this->workers[i].pipe_fd = worker_pipes[i].pipes[1]; this->workers[i].writer_id = writer_pti; pid = swFactoryProcess_worker_spawn(factory, writer_pti, i); if (pid < 0) { swTrace("Fork worker process fail.Errno=%d\n", errno); return SW_ERR; } else { this->workers[i].pid = pid; } } swFactoryProcess_manager_loop(factory); break; default: this->manager_pid = pid; for (i = 0; i < this->worker_num; i++) { writer_pti = (i % this->writer_num); #ifndef SW_USE_SHM_CHAN this->writers[writer_pti].reactor.add(&(this->writers[writer_pti].reactor), worker_pipes[i].pipes[0], SW_FD_PIPE); #endif close(worker_pipes[i].pipes[1]); this->workers[i].pipe_fd = worker_pipes[i].pipes[0]; this->workers[i].writer_id = writer_pti; } break; case -1: swTrace("[swFactoryProcess_worker_start]fork manager process fail\n") ; return SW_ERR; } return SW_OK; }
static int swFactoryProcess_manager_loop(swFactory *factory) { int pid, new_pid; int i; int reload_worker_i = 0; int reload_worker_num; int ret; int worker_exit_code; SwooleG.use_signalfd = 0; SwooleG.use_timerfd = 0; memset(&ManagerProcess, 0, sizeof(ManagerProcess)); swServer *serv = factory->ptr; swWorker *reload_workers; if (serv->onManagerStart) { serv->onManagerStart(serv); } reload_worker_num = serv->worker_num + SwooleG.task_worker_num; reload_workers = sw_calloc(reload_worker_num, sizeof(swWorker)); if (reload_workers == NULL) { swError("malloc[reload_workers] failed"); return SW_ERR; } //for reload swSignal_add(SIGTERM, swManager_signal_handle); swSignal_add(SIGUSR1, swManager_signal_handle); swSignal_add(SIGUSR2, swManager_signal_handle); //swSignal_add(SIGINT, swManager_signal_handle); while (SwooleG.running > 0) { pid = wait(&worker_exit_code); if (pid < 0) { if (ManagerProcess.reloading == 0) { swTrace("wait() failed. Error: %s [%d]", strerror(errno), errno); } else if (ManagerProcess.reload_event_worker == 1) { memcpy(reload_workers, serv->workers, sizeof(swWorker) * serv->worker_num); reload_worker_num = serv->worker_num; if (SwooleG.task_worker_num > 0) { memcpy(reload_workers + serv->worker_num, SwooleG.task_workers.workers, sizeof(swWorker) * SwooleG.task_worker_num); reload_worker_num += SwooleG.task_worker_num; } reload_worker_i = 0; ManagerProcess.reload_event_worker = 0; goto kill_worker; } else if (ManagerProcess.reload_task_worker == 1) { if (SwooleG.task_worker_num == 0) { swWarn("Cannot reload workers, because server no have task workers."); continue; } memcpy(reload_workers, SwooleG.task_workers.workers, sizeof(swWorker) * SwooleG.task_worker_num); reload_worker_num = SwooleG.task_worker_num; reload_worker_i = 0; ManagerProcess.reload_task_worker = 0; goto kill_worker; } } if (SwooleG.running == 1) { for (i = 0; i < serv->worker_num; i++) { //compare PID if (pid != serv->workers[i].pid) { continue; } else { if (serv->onWorkerError != NULL && WEXITSTATUS(worker_exit_code) > 0) { serv->onWorkerError(serv, i, pid, WEXITSTATUS(worker_exit_code)); } pid = 0; while (1) { new_pid = swFactoryProcess_worker_spawn(factory, i); if (new_pid < 0) { usleep(100000); continue; } else { serv->workers[i].pid = new_pid; break; } } } } //task worker if (pid > 0) { swWorker *exit_worker = swHashMap_find_int(SwooleG.task_workers.map, pid); if (exit_worker != NULL) { swProcessPool_spawn(exit_worker); } } } //reload worker kill_worker: if (ManagerProcess.reloading == 1) { //reload finish if (reload_worker_i >= reload_worker_num) { ManagerProcess.reloading = 0; reload_worker_i = 0; continue; } ret = kill(reload_workers[reload_worker_i].pid, SIGTERM); if (ret < 0) { swSysError("[Manager]kill(%d) failed.", reload_workers[reload_worker_i].pid); continue; } reload_worker_i++; } } sw_free(reload_workers); //kill all child process for (i = 0; i < serv->worker_num; i++) { swTrace("[Manager]kill worker processor"); kill(serv->workers[i].pid, SIGTERM); } if (SwooleG.task_worker_num > 0) { swProcessPool_shutdown(&SwooleG.task_workers); } if (serv->onManagerStop) { serv->onManagerStop(serv); } return SW_OK; }