首页
下载
文档
社区
视频
捐赠
源代码
赞助商
AOT 编译器
AI 助理
商业产品
PHP AOT 原生编译器
Swoole-Compiler 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
work先Reactor线程发送消息,为什么不直接用自己的fd
最近在单步,worker进程on_receive后向client发送东西,经调试,发现最后调用到swWorker_send2reactor 有个问题,为什么不直接 ```c swWorker *worker = swServer_get_worker(serv, SwooleWG.id); ``` 而是 ```c int pipe_worker_id = reactor_id + (pipe_index * serv->reactor_num); swWorker *worker = swServer_get_worker(serv, pipe_worker_id); /** * Send data to ReactorThread */ int swWorker_send2reactor(swEventData *ev_data, size_t sendn, int fd) { int ret; swServer *serv = SwooleG.serv; /** * reactor_id: The fd in which the reactor. */ int reactor_id = ev_data->info.from_id; int pipe_index = fd % serv->reactor_pipe_num; /** * pipe_worker_id: The pipe in which worker. */ int pipe_worker_id = reactor_id + (pipe_index * serv->reactor_num); swWorker *worker = swServer_get_worker(serv, pipe_worker_id); ```
发布于9年前 · 0 次浏览 · 来自
提问
m
member
最近在单步,worker进程on_receive后向client发送东西,经调试,发现最后调用到swWorker_send2reactor 有个问题,为什么不直接 ```c swWorker *worker = swServer_get_worker(serv, SwooleWG.id); ``` 而是 ```c int pipe_worker_id = reactor_id + (pipe_index * serv->reactor_num); swWorker *worker = swServer_get_worker(serv, pipe_worker_id); /** * Send data to ReactorThread */ int swWorker_send2reactor(swEventData *ev_data, size_t sendn, int fd) { int ret; swServer *serv = SwooleG.serv; /** * reactor_id: The fd in which the reactor. */ int reactor_id = ev_data->info.from_id; int pipe_index = fd % serv->reactor_pipe_num; /** * pipe_worker_id: The pipe in which worker. */ int pipe_worker_id = reactor_id + (pipe_index * serv->reactor_num); swWorker *worker = swServer_get_worker(serv, pipe_worker_id); ```
赞
0
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
登录
后参与评论
评论
2017-05-21
嗼
嗼夨嗼莣
而且在发送的过程中,为什么没有加锁
赞
0
回复
2017-05-22
5
582***71
1. 发送到客户端,实际上先要找到对应的Reactor线程,计算方法是fd % server->reactor_num 2. `worker_num`如果是24个,`reactor_num`是4个,那么每个`Reactor线程`可以对应4个Worker进程的管道,也就是说发送用的管道实际上和Worker进程并不是绑定关系,实际上是和`Reactor线程`绑定的,`pipe_index`用来计算fd使用哪个管道 3. 写管道的操作是系统调用,所以不需要加锁。仅在写入超过`8180`字节时需要先写共享内
赞
0
回复
2017-05-22
迷
迷离
感谢你周末还在回答问题 你的回答中,第一点,Reactor线程id其实很容易确认,就是收到消息中的from_id 第二点,你的回答还是有点不明白,worker_num24个,reactor_num4个,为什么Reactor线程对应4个,个人感觉应该是6个, 还有,这里传进来的fd其实是session_id,并不是con的句柄fd,所以这个地方还是不太清楚,但是不管pipe_index取什么值,都会发送到对应的reactor线程,因为reactor_id + (pipe_index * serv-
赞
0
回复
2017-05-22
s
shi
因为swWorker_send2reactor中传入的fd为connetcion的session_id,我后面又仔细想了一下,这里,你的这个算法 int pipe_worker_id = reactor_id + (pipe_index * serv->reactor_num); 还是有必要的,起一个负载均衡的作用,通过session_id来做,保证到reactor线程的通讯,每个管道都平均的发送 线程安全的那个我查了一下,小于一定数值内是线程安全的,你的8180是如何得到的,因为貌似跟系统
赞
0
回复