× 警告!旧版文档已经暂停维护,请查看新版文档。点击前往新版文档

onWorkerStart

此事件在Worker进程/Task进程启动时发生。这里创建的对象可以在进程生命周期内使用。原型:

function onWorkerStart(swoole_server $server, int $worker_id);
  • onWorkerStart/onStart是并发执行的,没有先后顺序
  • 可以通过$server->taskworker属性来判断当前是Worker进程还是Task进程
  • 设置了worker_numtask_worker_num超过1时,每个进程都会触发一次onWorkerStart事件,可通过判断$worker_id区分不同的工作进程
  • 由 worker 进程向 task 进程发送任务,task 进程处理完全部任务之后通过onFinish回调函数通知 worker 进程。例如,我们在后台操作向十万个用户群发通知邮件,操作完成后操作的状态显示为发送中,这时我们可以继续其他操作。等邮件群发完毕后,操作的状态自动改为已发送。

注意事项

  • 发生致命错误或者代码中主动调用exit时,Worker/Task进程会退出,管理进程会重新创建新的进程。这可能导致死循环,不停地创建销毁进程

下面的示例用于为Worker进程/Task进程重命名。

$serv->on('WorkerStart', function ($serv, $worker_id){
    global $argv;
    if($worker_id >= $serv->setting['worker_num']) {
        swoole_set_process_name("php {$argv[0]} task worker");
    } else {
        swoole_set_process_name("php {$argv[0]} event worker");
    }
});

如果想使用Reload机制实现代码重载入,必须在onWorkerStartrequire你的业务文件,而不是在文件头部。在onWorkerStart调用之前已包含的文件,不会重新载入代码。

可以将公用的、不易变的php文件放置到onWorkerStart之前。这样虽然不能重载入代码,但所有Worker是共享的,不需要额外的内存来保存这些数据。
onWorkerStart之后的代码每个进程都需要在内存中保存一份

  • $worker_id是一个从[0-$worker_num)区间内的数字,表示这个Worker进程的ID
  • $worker_id和进程PID没有任何关系,可使用posix_getpid函数获取PID

协程支持

2.1.0版本onWorkerStart回调函数中创建了协程,在onWorkerStart可以调用协程API


  • 屏风山下的猎人

    看到这里终于明白了,如果不设置worker_num,默认一个主进程,一个管理进程,一个worker进程 会看到三个进程

  • 何向成

    global $argv 这个变量,是在该worker进程内的全局变量吧?

  • 世界不可能那么远啊

    在onWorkerStart中怎么获取PID?

  • 一夜坎坷

    这个回调函数中传入的 swoole_server 是work进程,还是master进程,还是管理进程。

  • ゛心如直水;

    //定时器 $ws->on('WorkerStart', function (\swoole_server $server, $worker_id) {

     if ($server->worker_id == 0){//防止重复
    
        //每隔2000ms触发一次
        swoole_timer_tick(2000, function ($timer_id) {
    
           // echo "tick-2000ms\n";
    
            for($i=1;$iserver($i,'可以这样定时推送吗');
            }
    
        });
    
    
    }
    

    });

  • ゛心如直水;

    //定时器 $ws->on('WorkerStart', function (\swoole_server $server, $worker_id) {

     if ($server->worker_id == 0){//防止重复
    
        //每隔2000ms触发一次
        swoole_timer_tick(2000, function ($timer_id) {
    
           // echo "tick-2000ms\n";
    
            for($i=1;$iserver($i,'可以这样定时推送吗');
            }
    
        });
    
    
    }
    

    });

  • ゛心如直水;

    //定时器 $ws->on('WorkerStart', function (\swoole_server $server, $worker_id) {

     if ($server->worker_id == 0){//防止重复
    
        //每隔2000ms触发一次
        swoole_timer_tick(2000, function ($timer_id) {
    
           // echo "tick-2000ms\n";
    
            for($i=1;$i server ($i,'可以这样定时推送吗');
            }
    
        });
    
    
    }
    

    });

  • ゛心如直水;

    for($i=1;$iserver($i,'可以这样定时推送吗'); }

  • 一场白雪

    $worker_id是一个从0-$worker_num之间的数字 应该是 $worker_id是一个从0-$worker_num-1之间的数字 ?

  • 虚空墨迹

    此写法只有一个event进程在运行, 如果worker_num大于1,那么除worker_id==0的进程会运行,剩余进程则是空进程

    if ($server->worker_id == 0){//防止重复 //每隔2000ms触发一次 swoole_timer_tick(2000, function ($timer_id) {

       // echo "tick-2000ms\n";
        for($i=1;$i server ($i,'可以这样定时推送吗');
        }
    });
    

    }