/** * 使用Unix Socket通信 */ int swFactoryProcess_writer_loop_unsock(swThreadParam *param) { swFactory *factory = param->object; swFactoryProcess *object = factory->object; int pti = param->pti; swReactor *reactor = &(object->writers[pti].reactor); struct timeval tmo; tmo.tv_sec = 3; tmo.tv_usec = 0; reactor->factory = factory; reactor->id = pti; //worker过多epoll效率更高 if (swReactor_auto(reactor, SW_REACTOR_MAXEVENTS) < 0) { pthread_exit((void *) param); return SW_ERR; } swSingalNone(); reactor->setHandle(reactor, SW_FD_PIPE, swReactorThread_onPipeReceive); reactor->wait(reactor, &tmo); reactor->free(reactor); pthread_exit((void *) param); return SW_OK; }
static int swFactoryProcess_worker_loop(swFactory *factory, int worker_pti) { struct { long pti; swEventData req; } rdata; swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; int pipe_rd = object->workers[worker_pti].pipe_worker; int n; c_worker_pti = worker_pti; object->manager_pid = getppid(); #if SW_WORKER_IPC_MODE == 2 //抢占式,使用相同的队列type if (serv->dispatch_mode == SW_DISPATCH_QUEUE) { //这里必须加1 rdata.pti = serv->worker_num + 1; } else { //必须加1 rdata.pti = worker_pti + 1; } #else SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if(SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor fail"); return SW_ERR; } if(swReactor_auto(SwooleG.main_reactor, serv->max_conn) < 0) { swError("[Worker] create worker_reactor fail"); return SW_ERR; } SwooleG.main_reactor->ptr = serv; SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_rd, SW_FD_PIPE); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swFactoryProcess_worker_receive); #endif if(factory->max_request < 1) { worker_task_always = 1; } else { worker_task_num = factory->max_request; worker_task_num += get_rand(worker_pti); } #ifdef HAVE_CPU_AFFINITY if (serv->open_cpu_affinity == 1) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(worker_pti % SW_CPU_NUM, &cpu_set); if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set)) { swWarn("pthread_setaffinity_np set fail\n"); } } #endif if (serv->onWorkerStart != NULL) { //worker进程启动时调用 serv->onWorkerStart(serv, worker_pti); } struct timeval timeo; timeo.tv_sec = SW_REACTOR_TIMEO_SEC; timeo.tv_usec = SW_REACTOR_TIMEO_USEC; #if SW_WORKER_IPC_MODE == 2 //主线程 while (swoole_running > 0) { n = object->rd_queue.out(&object->rd_queue, (swQueue_data *)&rdata, sizeof(rdata.req)); if (n < 0) { swWarn("[Worker]rd_queue[%ld]->out wait. Error: %s [%d]", rdata.pti, strerror(errno), errno); continue; } swFactoryProcess_worker_excute(factory, &rdata.req); } #else SwooleG.main_reactor->wait(SwooleG.main_reactor, &timeo); #endif if (serv->onWorkerStop != NULL) { //worker进程结束时调用 serv->onWorkerStop(serv, worker_pti); } swTrace("[Worker]max request\n"); return SW_OK; }
/** * worker main loop */ static int swFactoryProcess_worker_loop(swFactory *factory, int worker_pti) { swFactoryProcess *object = factory->object; swServer *serv = factory->ptr; struct { long pti; swEventData req; } rdata; int n; int pipe_rd = object->workers[worker_pti].pipe_worker; #ifdef HAVE_CPU_AFFINITY if (serv->open_cpu_affinity == 1) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(worker_pti % SW_CPU_NUM, &cpu_set); if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set)) { swWarn("pthread_setaffinity_np set failed"); } } #endif //signal init swFactoryProcess_worker_signal_init(); //worker_id SwooleWG.id = worker_pti; #ifndef SW_USE_RINGBUFFER int i; //for open_check_eof and open_check_length if (serv->open_eof_check || serv->open_length_check) { SwooleWG.buffer_input = sw_malloc(sizeof(swString*) * serv->reactor_num); if (SwooleWG.buffer_input == NULL) { swError("malloc for SwooleWG.buffer_input failed."); return SW_ERR; } for (i = 0; i < serv->reactor_num; i++) { SwooleWG.buffer_input[i] = swString_new(serv->buffer_input_size); if (SwooleWG.buffer_input[i] == NULL) { swError("buffer_input init failed."); return SW_ERR; } } } #endif if (serv->ipc_mode == SW_IPC_MSGQUEUE) { //抢占式,使用相同的队列type if (serv->dispatch_mode == SW_DISPATCH_QUEUE) { //这里必须加1 rdata.pti = serv->worker_num + 1; } else { //必须加1 rdata.pti = worker_pti + 1; } } else { SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if (SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor failed."); return SW_ERR; } if (swReactor_auto(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) { swError("[Worker] create worker_reactor failed."); return SW_ERR; } swSetNonBlock(pipe_rd); SwooleG.main_reactor->ptr = serv; SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_rd, SW_FD_PIPE); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swFactoryProcess_worker_receive); #ifdef HAVE_SIGNALFD if (SwooleG.use_signalfd) { swSignalfd_setup(SwooleG.main_reactor); } #endif } if (factory->max_request < 1) { worker_task_always = 1; } else { worker_task_num = factory->max_request; worker_task_num += swRandom(worker_pti); } //worker start if (serv->onWorkerStart != NULL) { serv->onWorkerStart(serv, worker_pti); } if (serv->ipc_mode == SW_IPC_MSGQUEUE) { while (SwooleG.running > 0) { n = object->rd_queue.out(&object->rd_queue, (swQueue_data *)&rdata, sizeof(rdata.req)); if (n < 0) { if (errno == EINTR) { if (SwooleG.signal_alarm && serv->onTimer) { swTimer_select(&SwooleG.timer); SwooleG.signal_alarm = 0; } } else { swWarn("[Worker]rd_queue[%ld]->out wait failed. Error: %s [%d]", rdata.pti, strerror(errno), errno); } continue; } swFactoryProcess_worker_excute(factory, &rdata.req); } } else { struct timeval timeo; timeo.tv_sec = SW_REACTOR_TIMEO_SEC; timeo.tv_usec = SW_REACTOR_TIMEO_USEC; SwooleG.main_reactor->wait(SwooleG.main_reactor, &timeo); } if (serv->onWorkerStop != NULL) { //worker shutdown serv->onWorkerStop(serv, worker_pti); } swTrace("[Worker]max request"); return SW_OK; }
/** * worker main loop */ int swWorker_loop(swFactory *factory, int worker_id) { swServer *serv = factory->ptr; struct { long pti; swEventData req; } rdata; int n; #ifdef HAVE_CPU_AFFINITY if (serv->open_cpu_affinity == 1) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(worker_id % SW_CPU_NUM, &cpu_set); if (0 != sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set)) { swWarn("pthread_setaffinity_np set failed"); } } #endif #ifndef SW_WORKER_USE_SIGNALFD SwooleG.use_signalfd = 0; #endif //signal init swWorker_signal_init(); //worker_id SwooleWG.id = worker_id; int i; SwooleWG.buffer_input = sw_malloc(sizeof(swString*) * serv->reactor_num); if (SwooleWG.buffer_input == NULL) { swError("malloc for SwooleWG.buffer_input failed."); return SW_ERR; } #ifndef SW_USE_RINGBUFFER int buffer_input_size; if (serv->open_eof_check || serv->open_length_check || serv->open_http_protocol) { buffer_input_size = serv->package_max_length; } else { buffer_input_size = SW_BUFFER_SIZE_BIG; } for (i = 0; i < serv->reactor_num; i++) { SwooleWG.buffer_input[i] = swString_new(buffer_input_size); if (SwooleWG.buffer_input[i] == NULL) { swError("buffer_input init failed."); return SW_ERR; } } #endif if (serv->ipc_mode == SW_IPC_MSGQUEUE) { //抢占式,使用相同的队列type if (serv->dispatch_mode == SW_DISPATCH_QUEUE) { //这里必须加1 rdata.pti = serv->worker_num + 1; } else { //必须加1 rdata.pti = worker_id + 1; } } else { SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); if (SwooleG.main_reactor == NULL) { swError("[Worker] malloc for reactor failed."); return SW_ERR; } if (swReactor_auto(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) { swError("[Worker] create worker_reactor failed."); return SW_ERR; } int pipe_worker = serv->workers[worker_id].pipe_worker; swSetNonBlock(pipe_worker); SwooleG.main_reactor->ptr = serv; SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive); SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE | SW_EVENT_WRITE, swPipeUnsock_onWrite); } if (serv->max_request < 1) { SwooleWG.run_always = 1; } else { worker_task_num = serv->max_request; worker_task_num += swRandom(worker_id); } swWorker_onStart(serv); if (serv->ipc_mode == SW_IPC_MSGQUEUE) { while (SwooleG.running > 0) { n = serv->read_queue.out(&serv->read_queue, (swQueue_data *) &rdata, sizeof(rdata.req)); if (n < 0) { if (errno == EINTR) { if (SwooleG.signal_alarm) { SwooleG.timer.select(&SwooleG.timer); } } else { swWarn("[Worker%ld] read_queue->out() failed. Error: %s [%d]", rdata.pti, strerror(errno), errno); } continue; } swWorker_excute(factory, &rdata.req); } } else { #ifdef HAVE_SIGNALFD if (SwooleG.use_signalfd) { swSignalfd_setup(SwooleG.main_reactor); } #endif SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL); } swWorker_onStop(serv); return SW_OK; }