- 主题:觉得协程不是一个太好的编程模型
【 在 hgoldfish 的大作中提到: 】
: 是 mmap(MAP_STACK) 吗? 如果不是的话,mmap() 也会提前分配出内存,非常浪费内存。
:
task->uc.uc_stack.ss_sp=mmap(0, use_stack_size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN, -1, 0);
MAP_GROWSDOWN不就是指的向下生长?
当年没有发现MAP_STACK选项。
应该还有那些设置项?
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
【 在 hgoldfish 的大作中提到: 】
: 是 mmap(MAP_STACK) 吗? 如果不是的话,mmap() 也会提前分配出内存,非常浪费内存。
:
请教一下,用过MS的IOCP吗?
可以一个线程守护很多其他线程提交的完成事件吗?
可以多个线程守护这些事件吗?
linux的AIO是自己提交的任务自己守护,但是可以绑定一个eventfd,把这个fd排队到epoll,就可以一大堆线程守护一大堆fd。
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
【 在 hgoldfish 的大作中提到: 】
: 有 MAP_GROWDOWN 就是对的。不会全部分配。
: MAP_STACK 在 Linux 是 no-op,但是在 openbsd 里面是有效的。
: 想要跨多种平台的话,最好也加上。
: ...................
OK,多谢。
--
FROM 221.218.60.*
哦,说说看,学习学习。
如何一(几)个线程提交,另一(几)个线程守护。像epoll那样使用。
【 在 z16166 的大作中提到: 】
: IOCP我用过,你问的两个,答案都是yes
:
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
不是这个意思。
是一个连接可以被任何一个线程处理,任何时候可以被任何线程丢进事件队列,并立即生效。队列可以被任意线程守候,但是一个fd只能激活一个线程,只能有一个线程持有。
许多线程守护许多socket。
这是作为线程调度器的基础。
许多线程把许多事件丢进一个队列并由许多线程守护,
但是一个线程只处理一个事件。
如果一个事件被多个线程捕获,就叫做 惊群,epoll是有惊群的,要设法避免。
【 在 hgoldfish 的大作中提到: 】
: 对。但是我的理解是这个用法多个线程一起服务同一个 socket 没有太大的意义吧?
: 你们是什么场景中,需要由多个线程来处理同一条 TCP 连接的?
:
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
这个正是我想知道的,请详细介绍。
138楼我啰嗦了,就是要N个线程守候M个连接的方法。
已经提交的handle,送哪儿排队,如何守护?
【 在 z16166 的大作中提到: 】
: 收发全双工就是一种场景吧
: http是一收一发,其他的协议/场景是可能有收的同时也在发的,一个线程负责收,一个线程负责发。
: IOCP是n个线程处理m个连接,以WSASend()/WSARecv()请求的完成结果作为派发单位,派发给对应的线程(优先派发给正在运行的线程,减少线程切换开销),不管是哪个tcp连接的。当然,派发信息里携带的有是哪个tcp连接的context信息的(completion key。overlapped结构也可以扩展一下,存放自己的连接信息)。
: ...................
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
多谢。
【 在 z16166 的大作中提到: 】
: 排队和派发是windows内核实现的,并不开源,哈哈
: 让chatgpt帮你写个简单的IOCP例子就知道了
: 或者MS的这个例子
: ...................
--
FROM 221.218.60.*
全双工服务器远比你想象的复杂,典型的游戏服务器,有成千上万的客户端接入。
每一个accept的客户端,创建一个与socket关联的task,在系统中注册,一个新玩家。
随后这个task被丢进M:N的调度器,如epoll,准备接收它的信息。这个task不可以向自己的socket发送信息,因为别人也可以发,会打架。
如果需要发信息,把task+信息发送到一个队列,有一个线程守候这个队列,收到一个信息就把它发到对应的socket。
如果觉得吞吐量不够需要多加线程的话,需要考虑一个socket不能同时两个操作,搞点锁呀排队呀什么的。
在release task时,必须要考虑是否还在被使用。
所以我的问题是,什么东西可以搞M:N调度器,IOCP行吗?
据我所知,还有bsd的kqueue,线程条件锁。
【 在 hgoldfish 的大作中提到: 】
: 这种场景是 IO 非常大的时候用的?
: 线程1: 读数据, 处理数据, 读数据, 处理数据
: 线程2: 写数据, 准备数据, 写数据,准备数据
: ...................
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
有成千上万个客户端接入的时候,才应该使用 m:n 模型。
n就是核数,当n全部忙起来的时候,就是系统最大能力发挥出来的时候。如果还有未决的任务,让它们排队等着,就是最好的,真要是建立成千上万的线程,大量时间花在调度上,会严重影响系统性能。
就像公共汽车,大家一拥而上,谁也上不去,排个队才好。
搞交易中间件的都知道,如果成千上万的客户端直接连数据库,很容易把数据库憋死。通过中间件,才能使系统运行顺畅,就是靠的中间件的M:N的功能。
如果系统能力不够,就增加核数,或增加服务器数量。
另外,调度器的性能,可以有一个指标反映:
最大响应时间:平均响应时间。
TUXEDO做到9,我的可以做到1.25。
【 在 hgoldfish 的大作中提到: 】
: 有成千上万个客户端接入的时候,才不应该使用 m:n 模型啊。此时一个 socket fd 的收发各使用一个线程,和一整个 socketfd 在一个线程内处理没啥区别。
: m:n 模式最好的地方应该是那种超大带宽超大吞吐连接数量不多的场景才对。
:
--
修改:ylh1969 FROM 221.218.60.*
FROM 221.218.60.*
所以说,协程的低成本切换没啥用。M:N的线程池模型已经完美解决CPU资源充分利用的问题,实现了0成本切换。
协程的意义在于,在M:N模型中,task陷入等待IO期间,能够释放线程,让它及时服务于等待处理的大批任务。
【 在 ylh1969 的大作中提到: 】
: 有成千上万个客户端接入的时候,才应该使用 m:n 模型。
: n就是核数,当n全部忙起来的时候,就是系统最大能力发挥出来的时候。如果还有未决的任务,让它们排队等着,就是最好的,真要是建立成千上万的线程,大量时间花在调度上,会严重影响系统性能。
: 就像公共汽车,大家一拥而上,谁也上不去,排个队才好。
: ...................
--
FROM 221.218.60.*