程序中监听的含义?

2019-09-11 20:18:27 +08:00
 smallpython
是不是就是说死循环去访问一个资源?

比如监听端口

就是一个死循环的程序去检查这个端口有没有数据被传输进来?

如果是的话,那么每次检查的间隔时间一般都设置为多久呢?
7027 次点击
所在节点    程序员
47 条回复
soulzz
2019-09-11 20:21:22 +08:00
建议了解下 nio
xeaglex
2019-09-11 20:43:37 +08:00
监听无非就两大类:主动轮询,或者被动通知。

轮询就是像你说的,疯狂检查。通知就比如现在常说的异步机制。
zxle
2019-09-11 20:45:39 +08:00
lz 说的这种方式一般属于操作系统层面干的活儿
seeker
2019-09-11 20:46:47 +08:00
监听是啥含义最好看看是啥场景,可能不好概括。
如果你说的是 linux c 语言 socket 编程,那么是先 bind ip 端口,然后死循环 accept,没有间隔时间,因为 accept 函数是阻塞的。
高级语言 /框架可能用 listen 而不是用 bind 最为函数 /方法名,做的事情很可能有区别。不过底层的话,应该差不多。
Fishdrowned
2019-09-11 21:08:30 +08:00
没错,最终需要有人在那里死循环
wwbfred
2019-09-11 21:18:23 +08:00
个人理解的监听就是轮询.
无论上层表现成什么方便高效的方式,底层都是轮询.
只是不同的轮询方式效率不同.
如果有误还请指正~
Buges
2019-09-11 21:21:46 +08:00
应该不能说是死循环,而是“等待”(也就是阻塞)
Fishdrowned
2019-09-11 21:22:57 +08:00
监听端口的话估计是这样:
网卡收到报文 -> 发起硬件中断 -> CPU 停下来处理这个中断 -> OS 中断处理 -> 应用程序

这样看起来不清楚 OS 是否需要死循环,或许不需要
Fishdrowned
2019-09-11 21:23:48 +08:00
不过 CPU 就是在无时无刻地死循环,这个是跑不了的
billlee
2019-09-11 21:34:11 +08:00
@Fishdrowned #9 CPU 明明可以 halt 的
lilydjwg
2019-09-11 21:38:39 +08:00
@Fishdrowned #9 不对。网络处理有两种方式:轮询和中断。通用计算机中,通常操作系统会通过中断的方式来获知有新数据到达。

CPU 没事干了怎么办?降频省电啊!一直没事干怎么办?电力紧张的话(比如移动设备),可以休眠啊。

至于用户态的监听( listen )。呃,它就是设置一下连接的状态而已……用户态程序要获知新数据的到达,需要使用阻塞调用( accept )、I/O 复用接口( epoll / poll / select )、异步 I/O 等方案。
lilydjwg
2019-09-11 21:43:19 +08:00
@seeker #4 你没分清楚 bind 和 listen 是干什么的。bind 是绑定本地地址。listen 是设置 TCP / UNIX 套接字的状态,好让内核能够相应的处理。

正常工作的网络程序,也不是写个死循环 accept 就完事了。阻塞方案的方案,为实际处理事务需要通过子进程 / 线程来处理连接。调用 accept 的线程需要立即重新 accept 以等待下一个连接。不要写成我学编程的那样,不能同时处理多个连接……

accept 是阻塞的这说法也不对。accept 是否阻塞,取决于套接字是否设置了 O_NONBLOCK 标志。
seeker
2019-09-11 22:28:38 +08:00
@lilydjwg 谢谢指正。
starsriver
2019-09-12 06:50:47 +08:00
如果你了解硬件设备,你就会知道看门狗而不会来问这么蠢的问题。

虽然现代计算机端口属于软件领域,但是和硬件差不多也有看门狗,不可能死循环轮寻,win10 的程序无响应了解一下?其实主要是基于任务调度,os 的触发器,就是别人说的中断。每个任务,进程,线程都有自己的编号 pid,而 cpu 每时每刻都会产生随即数来决定该为哪个服务分配资源,就行隔离,这部分基于硬件。端口也可以看作一个固定的分配号,当对应编号及缓存地址存在数据缓存或者出现头数据,触发器会开始工作,向 cpu 请求处理,处理完后数据被寄存到内存里,当前任务完成并通知其他任务继续进行
mikulch
2019-09-12 06:53:53 +08:00
挺感兴趣这个话题的,希望有人能够通俗易懂的讲清楚。
jedihy
2019-09-12 07:06:38 +08:00
OS 不会死循环的。

Windows:
网络 IO 都是 INT->ISR->Queue DPC ==> NDIS DPC -> LWF chain -> TCPIP (-> AFD -> Winsock1)
xuxuzhaozhao
2019-09-12 07:22:01 +08:00
@starsriver 你打娘胎生下来就会???这个弱智那个弱智,你才最弱智。
smallpython
2019-09-12 09:51:44 +08:00
@Fishdrowned 明白了,程序里设置的一旦触发了什么事件就去做什么事的这种逻辑.是利用了 cpu 是在无限死循环的特征.因为如果 cpu 不循环的话,那么它就停止了.
既然 cpu 是在死循环, 那么操作系统就可以利用这个循环来实现如上所述的"触发"这个动词的效果,就可以实现通知的功能.
就好像我并没有主动监听小明的声音,但是只要小明说话了,我就可以接受到小明的声音,这是因为我的大脑本身是在监听外部的所有信息,所以我的耳朵就不需要主动去监听小明的声音,就可以实现小明的声音触发我的动作这种效果.
可以这样理解吗?
smallpython
2019-09-12 10:00:07 +08:00
@lilydjwg 可是当中断的时候, 程序又是怎么知道它什么时候该继续呢?
我的理解还是因为它轮询的判断了某一个条件, 然后才能知道是不是该继续了.
表述可能有点拟人化,但是我觉得这个道理应该是成立的.

就好像单核的多进程是 CPU 快速切换的假象,而不是真的有多个进程
我想知道所谓的中断,在最底层的实现,是不是也得有一个死循环的判断逻辑
jworg
2019-09-12 10:01:47 +08:00
@smallpython 这里的部分回答应该能解释部分吧 https://www.zhihu.com/question/21440586

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/600158

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX